我正在开发一个(相当)简单的2D项目。这是某种小行星克隆。
该船基本上是一个高度为H的等腰三角形,底座的长度为H / 2.
到目前为止,我一直在做的方法就是存储三角形的中心点(CP),然后动态计算最终的顶点位置。船的“点”是(向量是x,y)(CP.x,CP.y + H / 2)。另外两点是(CP.X - H / 4,CP.Y - H / 2)和(CP.X + H / 4,CP.Y - H / 2)。
为了使船朝向正确的方向,我首先在当前的旋转角度上调用glRotate。
这部分工作正常但是我遇到了碰撞检测的问题。目前我正在尝试实现三角平面碰撞检测,但是为了做到这一点,我首先需要弄清楚旋转后船顶点的实际点。我尝试使用三角法来计算这些点,但是我失败了。
我尝试的方法是使用余弦规则来找到旋转后未旋转三角形和三角形之间的距离。举一个例子,以下是我在旋转后尝试计算'尖头'顶点位置的方法:
//pA is a vector struct holding the position of the pointy vertex of the ship (centerPoint.x, centerPoint.y + height / 2)
//Distance between pA and the rotated pointy vertex - using the cosine rule
float distance = sqrt((2 * pow(size / 2, 2)) * (1 - cosf(rotAngle)));
//The angle to the calculated point
float newPointAngle = (M_PI / 2) - rotAngle;
float xDif = distance * cosf(newPointAngle);
float yDif = distance * sinf(newPointAngle);
//Actually drawing the new point
glVertex2f(pA.x - xDif, pA.y - yDif);
知道我可能做错了吗?
答案 0 :(得分:4)
感谢帮助人员,但我认为这些解释对我来说有点太技术性了。尽管如此,你向我明确表示三角形没有特殊情况(后见之明,我应该知道)所以我尝试了搜索并尝试了几种方法后找到了一个适合我的方法。
来自GameDev forums的estain的帖子做了伎俩。引用他的帖子(对c& p感到抱歉,但对遇到类似问题的其他人可能有用):
没有深入研究一般的解决方案和数学(正如上面的海报和许多文章已经涵盖了这一点),我可以给你一个如何解决问题的例子“在C点绕B点旋转A点”
现在。首先,正如我在前一篇文章中所描述的那样,在X轴上的一个点,与原点的距离为L,在原点周围旋转了C度
x = L * cos(C)
y = L * sin(C)
类似地,垂直向量的公式是x = -y | y = x,这意味着Y轴上的点(再次,来自原点的L)将使用公式C旋转
x = - L * sin(C)
y = L * cos(C)
如上图所示,最终解是投影向量的旋转之和,因此我们可以导出公式
x'= x * cos(C) - y * sin(C)
y'= y * cos(C)+ x * sin(C)
......但你已经知道了,对吗?问题是,这个公式只围绕origo旋转。所以我们需要做的是将我们旋转的坐标系移动到原点,旋转然后向后移动。这可以通过复杂的数字或使用矩阵的一般解决方案快速完成,但我们将坚持使用矢量数学来保持简单。
第一步;移动原点。x'= A.x - B.x
y'= A.y - B.y
第二步,执行轮换
x''= x'* cos(C) - y'* sin(C)=(A.x-B.x)* cos(C) - (A.y-B.y)* sin(C)
y''= y'* cos(C)+ x'* sin(C)=(A.y-B.y)* cos(C)+(A.x-B.x)* sin(C)
第三步也是最后一步,移回坐标框
x'''= x''+ B.x =(A.x-B.x)* cos(C) - (A.y-B.y)* sin(C)+ B.x
y'''= y''+ B.y =(A.y-B.y)* cos(C)+(A.x-B.x)* sin(C)+ B.y
并且presto!我们有旋转公式。如果没有所有>计算,我会把它给你:
将点A绕点B旋转角度C
A.x'=(A.x-B.x)* cos(C) - (A.y-B.y)* sin(C)+ B.x
A.y'=(A.y-B.y)* cos(C)+(A.x-B.x)* sin(C)+ B.y
如果你一直在这里关注我(我是一个非常糟糕的老师,如果你没有,那就很抱歉),你可以确定你执行这些操作的顺序非常重要。尝试混合步骤3和1,看看你得到的公式的差异。
祝你好运!
答案 1 :(得分:2)
旋转计算需要以原点为中心,因此您可能需要首先平移坐标,以使旋转中心与原点对齐。
然后使用新点来获得旋转坐标:
x1 = x cos f - y sin f
y1 = y cos f + x sin f
其中f是旋转角度。
然后将新坐标转换回您开始的位置(与第一次翻译相反。
查看this article以获取一些图表和说明。
答案 2 :(得分:1)
计算新点相对简单。假设x和y是三角形上某个点(即顶点)相对于旋转点(或中心)的坐标。
您必须将坐标转换为方形距离和角度分量:
float dist, angle;
dist = (x*x) + (y*y);
angle = atan(abs(x)/abs(y));
// a little more code is required for the different quadrants that the angle could be in.
然后旋转:
angle+=rotation_angle;
然后转换回来:
new_x = sqrt(dist)*sin(angle*pi/180);
new_y = sqrt(dist)*cos(angle*pi/180);