Как вернуть все точки по кривой Безье?
Я опубликовал предыдущий вопрос о создании кривой Безье на основе только начальной и конечной точек, и благодаря ответам на этот вопрос я смог создать кривую Безье, используя имеющуюся у меня информацию.
Это код, который позволяет мне рисовать типы кривых, которые я хочу на форме.
private void Form1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Random rnd = new Random();
Point startp = new Point(rnd.Next(0, this.Width), rnd.Next(0, this.Height));
Point endp = new Point(rnd.Next(0, this.Width), rnd.Next(0, this.Height));
int xMod = 0;
int yMod = 0;
if (startp.X > endp.X) {
xMod = -1;
} else {
xMod = 1;
}
if (startp.Y > endp.Y) {
yMod = 1;
} else {
yMod = -1;
}
Point control1p = new Point(endp.X + (rnd.Next(20, 50) * xMod), endp.Y + (rnd.Next(20, 50) * yMod));
Point control2p = new Point(endp.X + (rnd.Next(5, 20) * xMod), endp.Y + (rnd.Next(5, 20) * yMod));
Point[] pts = {
startp,
control1p,
control2p,
endp
};
Pen dashed_pen = new Pen(Color.Black, 0);
dashed_pen.DashStyle = Drawing2D.DashStyle.Dash;
for (int i = 0; i <= 2; i++) {
e.Graphics.DrawLine(dashed_pen, pts(i), pts(i + 1));
}
e.Graphics.SmoothingMode = Drawing2D.SmoothingMode.HighQuality;
Pen bez_pen = new Pen(Color.Black, 3);
e.Graphics.DrawBezier(bez_pen, pts(0), pts(1), pts(2), pts(3))
}
Есть ли способ, или кто-то может помочь мне вернуть все точки, которые образуют кривую? Я бы хотел, чтобы каждая точка кривой, рассчитанная по этим точкам, возвращалась в массиве точек, но мне не повезло выяснить это, и я не смог найти аналогичное решение в stackru или в Google в генеральный.
Благодарю.
4 ответа
То, что вы хотите сделать, это преобразовать кривую Безье (кубическая от ее внешнего вида) в Polyline
Используйте уравнение на этой странице... Значение t
должно быть между 0 to 1
... Рассчитать все значения Bx(t)
а также By(t)
используя уравнение для значений t с шагом "0, 0.01, 0.02....1"
(Преобразовать их в integers
конечно) Чем меньше ваши приращения, тем точнее будут ваши очки.
Вот C- пример алгоритма Декастелау (почти такая же процедура, но я немного оптимизирован, я считаю):)
Идеальный алгоритм построения гладкой кривой Безье с оптимальным количеством точек описан Максимом Шеманаревым на странице "Антизерновая геометрия": Адаптивное подразделение кривых Безье.
Это может помочь, если вы используете lerp или float t производные в промежутке между рисованием безье. Я обнаружил, что это помогает с точностью; учитывая количество поплавков.
Я знаю, что это старый пост, но, не найдя ни одного удовлетворительного ответа на текущий момент, надеюсь, другие получат некоторую пользу от следующего:
using System.Collections.Generic;
using System.Drawing;
public List<Point> CubicBezierToPoints(Point P0, Point P1, Point P2, Point P3, double step = 0.01)
{
var pointList = new List<Point>();
for (var t = 0.00; t <= 1; t += step)
{
var x = Math.Pow(1 - t, 3) * P0.X + 3 * Math.Pow(1 - t, 2) * t * P1.X +
3 * (1 - t) * Math.Pow(t, 2) * P2.X + Math.Pow(t, 3) * P3.X;
var y = Math.Pow(1 - t, 3) * P0.Y + 3 * Math.Pow(1 - t, 2) * t * P1.Y +
3 * (1 - t) * Math.Pow(t, 2) * P2.Y + Math.Pow(t, 3) * P3.Y;
pointList.Add(new Point((int)x,(int)y));
}
return pointList;
}