我正在尝试制作一个三角形(等腰三角形)在屏幕上移动,同时当用户按下方向键(如右或左)时稍微旋转它。

我希望三角形的鼻子(顶点)始终引导三角形。 (就像那个古老的小行星游戏一样)。

我的问题在于背后的数学问题。在每个X时间间隔,我希望三角形在<!>“某个方向<!>”中移动,我需要帮助找到这个方向(x和y递增/递减)。

我可以找到三角形的中心点(Centroid),并且我有最高x和y点,所以我有一个线矢量可以使用,但不是<!>引用的线索;如何< !> QUOT;与之合作。

我认为它与旧的Sin和Cos方法以及三角形旋转的量(角度)有关,但我对这些东西有点生疏。

非常感谢任何帮助。

有帮助吗?

解决方案

vy / vx的反正切(反正切),其中vx和vy是你的(质心 - <!> gt; tip)矢量的组成部分,它给出了矢量所面对的角度。

经典的arctangent为你提供了一个标准化为-90 <!>#176的角度; LT <!>; r <!> lt; 90#176 <!>;但是,因此您必须根据结果的符号和vx的符号在结果中添加或减去90度。

幸运的是,您的标准库应该提供一个atan2()函数,该函数将vx和vy分别作为参数,并返回0 <!>#176之间的角度;和360 <!>#176;,或-180 <!>#176;和+180 <!>#176;度。它还将处理vx = 0的特殊情况,如果你不小心,这将导致除以零。

请参阅 http://www.arctangent.net/atan.html 或仅搜索for <!> quot; arctangent <!> quot;。

编辑:为了清晰起见,我在帖子中使用了学位,但Java和许多其他语言/库在弧度上工作,其中180 <!>#176; = <!>#960;。

您也可以将vx和vy添加到三角形的点以使其移动到<!>“forward <!>”;方向,但要确保向量标准化(vx <!>#178; + vy <!>#178; = 1),否则速度将取决于三角形的大小。

其他提示

@马克:

我已经尝试过两次在这个答案框中编写一个关于向量,坐标,点和角度的入门,但是在两个场合都改变了主意,因为它需要太长时间而且我确定有很多教程在那里解释东西比以往任何时候都好。

你的质心和<!> quot; tip <!> quot;坐标不是矢量;也就是说,将它们视为载体是没有任何好处的。

你想要的矢量vForward = pTip - pCentroid,可以通过减去<!> quot; tip <!>的坐标来计算。从质心点角落。此向量的atan2(),即atan2(tipY-centY,tipX-centX),为您提供三角形<!>“面对<!>”的角度。

至于它的相关性,无关紧要。你的图书馆可能会使用这样的惯例,即增加的X轴(--- <!> gt;右侧/东方向可能是你所见过的所有2D图形)都是0 <!>#176;或0 <!>#960;。增加的Y(顶部,北部)方向将对应于90 <!>#176;或(1/2)<!>#960;。

在我看来,您需要存储三角形的旋转角度以及可能的当前速度。

x' = x + speed * cos(angle)
y' = y + speed * sin(angle)

请注意,角度是弧度,而不是度数!

Radians = Degrees * RadiansInACircle / DegreesInACircle

RadiansInACircle = 2 * Pi

DegressInACircle = 360

对于顶点的位置,每个顶点位于距中心一定距离和角度。在执行此计算之前添加当前旋转角度。这与计算运动的数学计算方法相同。

还有一些:

向量表示位移。位移,翻译,移动或任何你想要称之为的东西,没有起点就没有意义,这就是为什么我提到了<!>“forward <!>”;上面的矢量为<!>;来自质心,<!>;这就是<!>“质心向量,<!>”的原因。具有质心点的x / y分量的向量没有意义。这些组件可以让您从原点移动质心点。换句话说,pOrigin + vCentroid = pCentroid。如果从0点开始,然后添加一个表示质心点位移的矢量,则得到质心点。

请注意:

vector + vector = vector
(增加两个位移会给你第三个不同的位移)

point + vector = point
(移动/移动一个点会给你另一个点)

point + point = ???
(添加两点没有意义;但是:)

point - point = vector
(两点的差异是它们之间的位移)

现在,可以(至少)以两种不同的方式考虑这些位移。你已经熟悉的是矩形(x,y)系统,其中矢量的两个分量分别代表x和y方向的位移。但是,您也可以使用极坐标坐标,(r,<!>#920;)。在这里,<!>#920;表示位移的方向(相对于任意零角度的角度)和r,距离。

以(1,1)向量为例。它代表了一个向右移动的单位,在我们以前习惯看到的坐标系中向上移动了一个单位。该向量的极性等价物是(1.414,45 <#176;);相同的运动,但表示为在45°#176; -angle方向上的1.414单位的位移。 (再次,使用方便的极坐标系,其中东方向为0 <!>#176;并且角度逆时针增加。)

极坐标和直角坐标之间的关系是:

<!>

<强>#920; = atan2(y,x)
r = sqrt(x <!>#178; + y <!>#178;)(现在你看到右三角形的位置了吗?)

反过来说,

x = r * cos(<!>#920;)
y = r * sin(<!>#920;)

现在,由于从三角形的质心绘制的线段到<!>“tip <!>”; corner代表你的三角形的方向<!> quot; facing,<!> quot;如果我们要获得与该行平行的向量(例如 vForward = pTip - pCentroid ),那个向量的<!>#920; -coordinate将对应于三角形所面对的角度。

再次取(1,1)向量。如果这是vForward,那就意味着你的<!> quot; tip <!>点的x和y坐标都比你的质心高1。让我们说质心开启(10,10)。这就是<!> quot; tip <!>转过来(11,11)。 (请记住, pTip = pCentroid + vForward ,将<!>“+ pCentroid <!>”添加到上一个等式的两边。)现在这个三角形面向哪个方向? 45 <!>#176 ;,对吗?那是我们(1,1)向量的<!>#920; -coordinate!

将质心保持在原点。使用从质心到鼻子的向量作为方向向量。 http://en.wikipedia.org/wiki/Coordinate_rotation#Two_dimensions 将轮流播放向量。从这个向量构造另外两个点。将这三个点转换为它们在屏幕上的位置并绘制。

double v; // velocity
double theta; // direction of travel (angle)
double dt; // time elapsed

// To compute increments
double dx = v*dt*cos(theta);
double dy = v*dt*sin(theta);

// To compute position of the top of the triangle
double size; // distance between centroid and top
double top_x = x + size*cos(theta);
double top_y = y + size*sin(theta);

我可以看到我需要将常用的2d旋转公式应用于我的三角形以获得我的结果,我只是在这里不同组件之间的关系有点麻烦。

aib ,声明:

  

反正切(反正切)   vy / vx,其中vx和vy是   你的组件(质心 - <!> gt;提示)   矢量,给你角度矢量   正面临着。

vx和vy是中心或尖端的x和y坐标吗?我想我对<!> quot; vector <!>的术语感到困惑。这里。我的印象是Vector只是2d(在这种情况下)空间中代表方向的一个点。

所以在这种情况下,如何计算质心 - <!> gt;提示的向量?它只是中心吗?

meyahoocomlorenpechtel 声明:

  

在我看来,你需要存储   三角形的旋转角度   可能是目前的速度。

相对于旋转角度是多少?三角形的起源,还是游戏窗口本身?此外,对于将来的旋转,角度是与最后一次旋转的角度还是三角形的原始位置?

感谢所有人的帮助,我非常感谢!

你会希望最顶端的顶点是质心,以达到预期的效果。

首先,我将从质心开始而不是计算它。你知道质心的位置和三角形的旋转角度,我会用它来计算顶点的位置。 (我提前为任何语法错误道歉,我刚开始涉足Java。)

//起点

double tip_x = 10;
double tip_y = 10;

should be

double center_x = 10;
double center_y = 10;

//三角形细节

int width = 6; //base
int height = 9;

应该是3个角度,距离对的数组。

angle = rotation_angle + vertex[1].angle;
dist = vertex[1].distance;    
p1_x = center_x + math.cos(angle) * dist;
p1_y = center_y - math.sin(angle) * dist;
// and the same for the other two points

请注意,我减去 Y距离。由于屏幕空间被颠倒,你被绊倒了。在我们看来,Y会随着你的上升而增加 - 但是屏幕坐标不会这样。

如果您将事物跟踪为位置和旋转角度而不是导出旋转角度,则数学运算会更简单。

此外,在最后一段代码中,您将按旋转角度修改位置。结果将是您的船在每个更新周期中按旋转角度旋转。我认为目标就像小行星,而不是追逐它的猫的尾巴!

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top