如何围绕抛物线旋转抛物线?

时间:2019-02-05 01:38:08

标签: math

我一直在打高尔夫球。我可以很容易地使用运动学方程画出球的预测运动抛物线。也就是说,我已经隔离了其运动的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怎么编码这个抛物线的旋转?

任何帮助将不胜感激!

1 个答案:

答案 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等),则可以将这些矩阵相乘并得到结果。也可以用笔和纸来获得它。

编辑:进行Maple乘法 enter image description here

文本中的最后一个表达式:

 (((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;

enter image description here