我一直在打高尔夫球。我可以很容易地使用运动学方程画出球的预测运动抛物线。也就是说,我已经隔离了其运动的x,y和z分量(这是3D抛物线)。现在,我试图找出旋转抛物线时如何绘制此预测线。当z分量等于0并且抛物线实际上是一条直线时,我已经成功完成了此操作。当运动存在z分量时,我遇到了困难。
我一直在使用这段代码来查找z分量抛物线的方程式,知道抛物线上的三个点(其中一个点始终为(0,0)一个是顶点,最后一个点(最大距离为0) ):
public void CalcParabolaVertex(float x1, float y1, float x2, float y2, float x3, float y3, out double xv, out double yv)
{
double denom = (x1 - x2) * (x1 - x3) * (x2 - x3);
double A = (x3 * (y2 - y1) + x2 * (y1 - y3) + x1 * (y3 - y2)) / denom;
double B = (x3 * x3 * (y1 - y2) + x2 * x2 * (y3 - y1) + x1 * x1 * (y2 - y3)) / denom;
double C = (x2 * x3 * (x2 - x3) * y1 + x3 * x1 * (x3 - x1) * y2 + x1 * x2 * (x1 - x2) * y3) / denom;
xv = -B / (2 * A);
yv = C - B * B / (4 * A);
}
知道抛物线y = ax2 + bx + c怎么编码这个抛物线的旋转?
任何帮助将不胜感激!
答案 0 :(得分:0)
编辑:适用于矢量绘图的简单方法:
为通常的抛物线生成点并围绕原点旋转它们:
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;