Редактировать: простой метод, подходящий для векторного рисования:
Создание точек для обычной параболы и вращение их вокруг начала координат:
for x with some step:
y = a * x*x + b *x + c
rx = x * cos(phi) - y * sin(phi)
ry = x * sin(phi) + y * cos(phi)
draw line to rx,ry
Код Delphi:
var
aa, bb, cc, y: Double;
Phi, cs, sn: Double;
X, xx, yy: Integer;
begin
X := -300;
aa := 0.01;
bb := 0;
cc := 0;
Phi := -Pi/4;
cs := Cos(Phi);
sn := Sin(Phi);
while X <= 200 do begin
y := aa * x * x + bb * x + cc * x;
xx := Round(200 + x * cs - y * sn); //+200 to draw in visible region
yy := Round(200 + x * sn + y * cs);
if x = -200 then
Canvas.MoveTo(xx, yy)
else
Canvas.LineTo(xx, yy);
X := X + 10;
end;
Обратите внимание, что повернутая парабола больше не может быть выражена как Y(x)
функция (представьте, парабола повернута на 90 градусов)
Общее уравнение квадратичной кривой
A*x^2 + B*x*y + C*y^2 + D*x + E*y + F = 0
В вашем случае
A = a; B,C=0; D=b; E=-1; F=c
То же общее уравнение в матричной форме
(ссылка: Rogers, Adams. Mathematical elements for computer graphics
книга)
|A B/2 D/2 | |x|
|x y 1| * |B/2 C E/2 | * |y| = 0
|D/2 E/2 F | |1|
или с использованием наших коэффициентов
|a 0 b/2 | |x|
|x y 1| * |0 0 -1/2 | * |y| = 0
|b/2 -1/2 c | |1|
Для вращения, мы должны умножить центральную матрицу на матрицу вращения слева и транспонированную матрицу вращения справа и получить окончательное уравнение.
Здесь cs=Cos(Phi)
и sn=Sin(Phi)
|cs -sn 0 | |a 0 b/2 | |cs sn 0 | |x|
|x y 1| * |sn cs 0 | * |0 0 -1/2 | * |-sn cs 0 | * |y| = 0
|0 0 1 | |b/2 -1/2 c | |0 0 1 | |1|
Если у вас есть некоторыеинструменты для символьных вычислений, такие как Maple, Matematica и т. д., вы можете умножить эти матрицы и получить результат.Его также можно получить ручкой и бумагой.
Редактировать: сделано умножение клена
Последнее выражение в тексте:
(((x*cs+y*sn)*a+1/2*b)*cs+1/2*sn)*x+
(((x*cs+y*sn)*a+1/2*b)*sn-1/2*cs)*y+
1/2*(x*cs+y*sn)*b+1/2*x*sn-1/2*y*cs+c
Собрав коэффициенты для x и y, мы получим коэффициенты общего уравнения
A = cs * cs * a
B = 2 * a * cs * sn
C = sn * sn * a
D = cs * b + sn
E = sn * b - cs
F = c
Подтверждение концепции: код Delphi генерирует параболу, повернутую на 45
var
aa, bb, cc, A, B, C, d, E, F: Double;
Phi, cs, sn: Double;
X, Y: Integer;
begin
aa := 0.01;
bb := 0;
cc := 0;
Phi := -Pi / 4;
cs := Cos(Phi);
sn := Sin(Phi);
A := cs * cs * aa;
B := 2 * aa * cs * sn;
C := sn * sn * aa;
d := cs * bb + sn;
E := sn * bb - cs;
F := cc;
for Y := -300 to 300 do
for X := -300 to 300 do
if Abs(A * X * X + B * X * Y + C * Y * Y + d * X + E * Y + F) <= 3 then
Canvas.Pixels[X + 300, Y + 300] := clRed;