2011-01-27 54 views
3

我想让一个2d精灵在“弧形”(半椭圆)而不是直线中移动。我有X和Y的开始和结束位置以及所需的半径。雪碧椭圆机芯

实现此目的的最佳方法是什么?

回答

0

如果你想让它移动到一个椭圆中,我知道的最简单的方法是将y值作为时间的函数与sin相乘,x值作为时间与cos的函数。假设你正在使用System.currentTimeMillis(),你可以将初始时间存储在一个变量中(例如double startTime = System.currentTimeMillis()),然后在每一帧中通过从当前时间减去当前时间开始时间。 (例如elapsedTme = System.currentTimeMillis() - startTime)。那么y值将是(y方向上的半径)* sin(elapsedTime * speed)+ y值,并且x值将是(x方向上的半径)* cos(elapsedTime * speed) +椭圆中心的x值。

编辑:如果你有起始的X和Y坐标,但不是椭圆的中心,那么我认为获得中心的最简单方法是找出其余的变量,然后将它们插入到方程。数学在那里不应该太难。

0

你可能会需要使用椭圆的参数表,这里显示

http://en.wikipedia.org/wiki/Ellipse#General_parametric_form

公式,因为你一开始PT和结束PT,你需要在两端在t解决,

然后从t开始到结束,以相对小的增量步进。

+0

翻译复杂的维基百科表达式为可用的代码是不是我的强项。该页面包含椭圆生成JavaScript,如果调整可以工作,但我不喜欢为每个精灵的每个运动矢量存储36(或多或少)点的想法。我希望有一个解决方案可以让我计算椭圆中任何地方的X和Y坐标,我希望类似于我在另一个应用中使用的一些旧的贝塞尔代码。 – latreides 2011-01-27 05:14:00

0

我认为这个问题最好通过一系列坐标变换来解决。为了符号简单,我们假设你有两点是u和v

假设你在一个非常简单的情况下工作 - 点u和v在(1,0)和(-1,0 ),并且椭圆上长轴的长度为1.然后,你只是描绘出一个半圆。假设你想在一个恒定的速度点之间进行插值,可以用以下公式:

x(t) = cos(pi * t) 
y(t) = sin(pi * t) 

当然,你不一定幸运地在此设置,所以我们可以做一系列的坐标转换将您带入此配置。对于初学者来说,让我们将点w定义为u =(x0,y0)和v =(x1,y1)之间的中间点。那就是:

w = (x2, y2) = ((x0 + x1)/2, (y0 + y1)/2) 

现在,假设你翻译u和v以便w在原点。这意味着u和v与相反向量的原点等距。如果我们使用矩阵和齐次坐标,那么你可以代表这是

 | 1 0 -x2 | 
T = | 0 1 -y2 | 
    | 0 0 1 | 

u和v的这个翻译后的位置,然后通过TuTv给出。我们称这些点为u'和v'。他们通过

u' = (x0 - x2, x1 - y2) = (x0/2 - x1/2, y0/2 - y1/2) 
v' = (x1 - x2, y1 - y2) = (x1/2 - x0/2, y1/2 - y0/2) 

给予我们现在已接近解决原来的问题,但我们有u“和v”没有很好地与x轴一致的问题,因为他们在原来的问题。为了解决这个问题,我们将应用旋转变换,以便u'结束于(1,0),v'结束于(0,1)。为此,我们需要建立一个坐标系统,其中一个基向量在u'方向,另一个在垂直于它的方向。为了做到这一点,我们来接我们单位向量如下:

e0 = u'/||u|| 
e1 = perp(e0) 

哪里perp垂直于e0一些单位向量。得到这个的一个方法就是说,如果e0 = (x3, y3),那么e1 = perp(e0) = (-y3, x3)。由于它们的点积为零,因此可以验证此矢量与(x3, y3)垂直。

鉴于这些载体,我们可以定义一个转换以将映射(1,0)至e0和(0,1)〜e1

|x3 -y3 0| 
|y3 x3 0| 
| 0 0 1| 

(即最后一列是齐次坐标系统)

当然,这与我们想要的相反 - 我们试图从e0到(1,0)和从e1到(0,1)映射。为了得到这个矩阵,我们只是反转上面的矩阵。幸运的是,因为我们选择e0e1是正交,上述矩阵是正交的,所以它的逆是其转置:

| x3 y3 0| 
R = |-y3 x3 0| 
    | 0 0 1| 

现在,如果我们应用Ru'v',我们结束与载体( 1,0)和(-1,0),这是我们希望他们成为的地方。现在的问题是我们想要追踪的椭圆不一定有单位高度。例如,如果我们将其高度叫做h,那么我们将追踪出半径为h和半微小轴1的椭圆路径。但这很容易用另一个坐标变换进行校正,这次按照因子1/h的比例缩放corodinate系统的高度,以便我们要追踪的椭圆的高度为1.这可以使用以下缩放矩阵完成:

| 1 0 0 | 
S = | 0 1/h 0 | 
    | 0 0 1 | 

之所以这样设置是有用的,我们知道,如果我们采取uv之间,然后期望的椭圆任意点矩阵SRT适用于它,那么我们将最终将其转换为使用相应的指向单位圆,这是从(1,0)到(-1,0)的路径。但更重要的是,这是相反的。如果我们将反向SRT应用于单位圆上的任意点,我们最终将返回uv之间的原始椭圆路径上的对应点!为了达成协议,我们知道如何找到从(1,0)到(-1,0)的路径上的点,所以我们有一个算法来解决这个问题:

  1. 对于给定的时间t,如果您在t时间从(1,0)移动到(-1,0),则找到您在单位圆上的位置。称它为p
  2. Compute p'=(SRT)-1 p。
  3. p'是你要找的点。

那么问题是什么(SRT)-1是。幸运的是,我们有(SRT)-1 = T -1 ř-1小号-1,并且所有这些矩阵的可以很容易地来计算:

 | 1 0 -x2 |   | 1 0 x2 | 
T = | 0 1 -y2 | T^-1 = | 0 1 y2 | 
    | 0 0 1 |   | 0 0 1 | 

    | x3 y3 0|   | x3 -y3 0 | 
R = |-y3 x3 0| R^-1 = | y3 x3 0 | 
    | 0 0 1|   | 0 0 1 | 

    | 1 0 0 |   | 1 0 0 | 
S = | 0 1/h 0 | S^-1 = | 0 h 0 | 
    | 0 0 1 |   | 0 0 1 | 

总之,最终的算法如下:

  1. 鉴于U =(X0,Y0)和v =(X1,Y1),让W =(X2,Y2)=((X0 + X1)/ 2,(Y0 + y1)/ 2)。
  2. 让u'= u/|| u || =(x3,y3)。
  3. 在时间t(0 ≤吨≤ 1),设p =(COS(π吨),SIN(π吨))
  4. 计算p” = S -1 P =(COS(π吨)中,h SIN(π吨))
  5. 计算p'= R -1 p” =(X3 COS(π吨) - Y3 SIN(π吨),Y3 COS(π吨)+ X3罪( π t))
  6. 计算p'''= T -1 p''=(x3cos(输出p'''作为您的观点。输入p'''作为您的观点。输入p'''作为您的观点。

对不起,如果这是一个很多的数学,但你的答案应该(希望!)由上述程序给出。

+0

这是很好的描述性的,但我没有看到我会用我的任何半径值修改值,以形成一个椭圆曲线而不是一个完美的球体。 – latreides 2011-01-29 19:37:25