4

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

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

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

我可以找到三角形的中心点(质心),并且我有最高的 x 和 y 点,所以我有一个线向量可以使用,但不知道“如何”使用它。

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

任何帮助是极大的赞赏。

4

9 回答 9

5

vy/vx 的反正切(反正切),其中 vx 和 vy 是 (centroid->tip) 向量的分量,为您提供向量所面对的角度。

然而,经典反正切为您提供了一个归一化为 -90° < r < +90° 度的角度,因此您必须根据结果的符号和 vx 的符号从结果中加上或减去 90 度。

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

请参阅http://www.arctangent.net/atan.html或仅搜索“arctangent”。

编辑:为了清楚起见,我在帖子中使用了度数,但 Java 和许多其他语言/库以 180° = π 的弧度工作。

您也可以将 vx 和 vy 添加到三角形的点以使其沿“向前”方向移动,但请确保向量已标准化(vx² + vy² = 1),否则速度将取决于三角形的大小。

于 2008-10-21T01:05:17.440 回答
4

It seems to me that you need to store the rotation angle of the triangle and possibly it's current speed.

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

Note that angle is in radians, not degrees!

Radians = Degrees * RadiansInACircle / DegreesInACircle

RadiansInACircle = 2 * Pi

DegressInACircle = 360

For the locations of the vertices, each is located at a certain distance and angle from the center. Add the current rotation angle before doing this calculation. It's the same math as for figuring the movement.

于 2008-10-21T01:08:23.847 回答
4

@Mark:

I've tried writing a primer on vectors, coordinates, points and angles in this answer box twice, but changed my mind on both occasions because it would take too long and I'm sure there are many tutorials out there explaining stuff better than I ever can.

Your centroid and "tip" coordinates are not vectors; that is to say, there is nothing to be gained from thinking of them as vectors.

The vector you want, vForward = pTip - pCentroid, can be calculated by subtracting the coordinates of the "tip" corner from the centroid point. The atan2() of this vector, i.e. atan2(tipY-centY, tipX-centX), gives you the angle your triangle is "facing".

As for what it's relative to, it doesn't matter. Your library will probably use the convention that the increasing X axis (---> the right/east direction on presumably all the 2D graphs you've seen) is 0° or 0π. The increasing Y (top, north) direction will correspond to 90° or (1/2)π.

于 2008-10-21T12:54:41.067 回答
4

Here's some more:

Vectors represent displacement. Displacement, translation, movement or whatever you want to call it, is meaningless without a starting point, that's why I referred to the "forward" vector above as "from the centroid," and that's why the "centroid vector," the vector with the x/y components of the centroid point doesn't make sense. Those components give you the displacement of the centroid point from the origin. In other words, pOrigin + vCentroid = pCentroid. If you start from the 0 point, then add a vector representing the centroid point's displacement, you get the centroid point.

Note that:

vector + vector = vector
(addition of two displacements gives you a third, different displacement)

point + vector = point
(moving/displacing a point gives you another point)

point + point = ???
(adding two points doesn't make sense; however:)

point - point = vector
(the difference of two points is the displacement between them)

Now, these displacements can be thought of in (at least) two different ways. The one you're already familiar with is the rectangular (x, y) system, where the two components of a vector represent the displacement in the x and y directions, respectively. However, you can also use polar coordinates, (r, Θ). Here, Θ represents the direction of the displacement (in angles relative to an arbitary zero angle) and r, the distance.

Take the (1, 1) vector, for example. It represents a movement one unit to the right and one unit upwards in the coordinate system we're all used to seeing. The polar equivalent of this vector would be (1.414, 45°); the same movement, but represented as a "displacement of 1.414 units in the 45°-angle direction. (Again, using a convenient polar coordinate system where the East direction is 0° and angles increase counter-clockwise.)

The relationship between polar and rectangular coordinates are:

Θ = atan2(y, x)
r = sqrt(x²+y²) (now do you see where the right triangle comes in?)

and conversely,

x = r * cos(Θ)
y = r * sin(Θ)

Now, since a line segment drawn from your triangle's centroid to the "tip" corner would represent the direction your triangle is "facing," if we were to obtain a vector parallel to that line (e.g. vForward = pTip - pCentroid), that vector's Θ-coordinate would correspond to the angle that your triangle is facing.

Take the (1, 1) vector again. If this was vForward, then that would have meant that your "tip" point's x and y coordinates were both 1 more than those of your centroid. Let's say the centroid is on (10, 10). That puts the "tip" corner over at (11, 11). (Remember, pTip = pCentroid + vForward by adding "+ pCentroid" to both sides of the previous equation.) Now in which direction is this triangle facing? 45°, right? That's the Θ-coordinate of our (1, 1) vector!

于 2008-10-22T00:32:02.360 回答
2

keep the centroid at the origin. use the vector from the centroid to the nose as the direction vector. http://en.wikipedia.org/wiki/Coordinate_rotation#Two_dimensions will rotate this vector. construct the other two points from this vector. translate the three points to where they are on the screen and draw.

于 2008-10-21T01:25:12.660 回答
0
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);
于 2008-10-21T01:11:24.637 回答
0

I can see that I need to apply the common 2d rotation formulas to my triangle to get my result, Im just having a little bit of trouble with the relationships between the different components here.

aib, stated that:

The arctangent (inverse tangent) of vy/vx, where vx and vy are the components of your (centroid->tip) vector, gives you the angle the vector is facing.

Is vx and vy the x and y coords of the centriod or the tip? I think Im getting confused as to the terminology of a "vector" here. I was under the impression that a Vector was just a point in 2d (in this case) space that represented direction.

So in this case, how is the vector of the centroid->tip calculated? Is it just the centriod?

meyahoocomlorenpechtel stated:

It seems to me that you need to store the rotation angle of the triangle and possibly it's current speed.

What is the rotation angle relative to? The origin of the triangle, or the game window itself? Also, for future rotations, is the angle the angle from the last rotation or the original position of the triangle?

Thanks all for the help so far, I really appreciate it!

于 2008-10-21T04:24:02.393 回答
0

you will want the topmost vertex to be the centroid in order to achieve the desired effect.

于 2008-10-21T04:30:56.963 回答
0

First, I would start with the centroid rather than calculate it. You know the position of the centroid and the angle of rotation of the triangle, I would use this to calculate the locations of the verticies. (I apologize in advance for any syntax errors, I have just started to dabble in Java.)

//starting point

double tip_x = 10;
double tip_y = 10;

should be

double center_x = 10;
double center_y = 10;

//triangle details

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

should be an array of 3 angle, distance pairs.

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

Note that I am subtracting the Y distance. You're being tripped up by the fact that screen space is inverted. In our minds Y increases as you go up--but screen coordinates don't work that way.

The math is a lot simpler if you track things as position and rotation angle rather than deriving the rotation angle.

Also, in your final piece of code you're modifying the location by the rotation angle. The result will be that your ship turns by the rotation angle every update cycle. I think the objective is something like Asteroids, not a cat chasing it's tail!

于 2008-10-30T05:14:08.397 回答