1. Overview
1.概述
When working with computer graphics and game development, the ability to rotate vertices around a certain point is a fundamental skill.
在处理计算机图形和开发游戏时,围绕某一点旋转顶点的能力是一项基本技能。
In this quick tutorial, we’ll explore different approaches to rotating a vertex around a certain point in Java.
在本快速教程中,我们将探讨在 Java 中围绕某一点旋转顶点的不同方法。
2. Understanding the Problem Statement
2.理解问题陈述
Let’s say we’ve two points on a 2D plane: point A with coordinates(x1, y1) and point B with coordinates (x2, y2). We want to rotate point A around point B by a certain degree. The direction of rotation is counter-clockwise if the rotation angle is positive and clockwise if the rotation angle is negative:
假设二维平面上有两个点:坐标为 (x1, y1) 的点 A 和坐标为 (x2, y2)的点 B。我们希望将点 A 绕点 B 旋转一定的角度。如果旋转角度为正,则旋转方向为逆时针;如果旋转角度为负,则旋转方向为顺时针:
In the above graph, point A’ is the new point after performing the rotation. The rotation from A to A’ is counter-clockwise, showing that the rotation angle is positive 45 degrees.
在上图中,A’点是旋转后的新点。从 A 点到 A’点的旋转是逆时针方向,表明旋转角度为正 45 度。
3. Using Origin as the Rotation Point
3. 使用原点作为旋转点 4.
In this approach, we’ll first translate the vertex and the rotation point to the origin. Once translated, we’ll apply the rotation around the origin by the required angle. After performing the rotation, we’ll translate them back to their original position.
在这种方法中,我们首先将顶点和旋转点平移到原点。平移后,我们将以所需的角度围绕原点进行旋转。完成旋转后,我们再将它们平移回原来的位置。<br
3.1. Rotate a Point P Around the Origin
3.1.将点 P 绕原点旋转
First, let’s understand how to rotate point P around the origin. For rotation, we’ll be using formulas that involve trigonometric functions. The formula for calculating the new coordinates for rotating a point P (x,y) around the origin (0,0) in a counter-clockwise direction is:
首先,让我们来了解如何将点 P 绕原点旋转。对于旋转,我们将使用涉及 三角函数的公式。将点 P (x,y) 绕原点 (0,0) 逆时针旋转的新坐标计算公式为:
rotatedXPoint = x * cos(angle) - y * sin(angle)
rotatedYPoint = x * sin(angle) + x * cos(angle)
The rotatedXPoint and rotatedYPoint represent the new coordinates of point P after it has been rotated. If we need to rotate the point clockwise, we need to use the negative rotation angle.
rotatedXPoint 和 rotatedYPoint 表示点 P 旋转后的新坐标。如果我们需要顺时针旋转点,则需要使用负旋转角。
3.2. Rotation Around a Given Point
3.2.绕给定点旋转
We’ll shift the rotation point to the origin by subtracting the x-coordinate of the rotation point from the x-coordinate of the vertex and similarly subtracting the y-coordinate of the rotation point from the y-coordinate of the vertex.
我们用顶点的 x 坐标减去旋转点的 x 坐标,再用顶点的 y 坐标减去旋转点的 y 坐标,从而将旋转点移至原点。
These translated coordinates represent the vertex position relative to this new origin. Afterward, we’ll perform the rotation as previously described and apply a reverse translation by adding back the x and y coordinates.
这些平移后的坐标表示顶点相对于新原点的位置。之后,我们将按照之前所述的方法进行旋转,并通过加回 x 坐标和 y 坐标来应用反向平移。
Let’s use this approach to rotate a vertex around a point:
让我们用这种方法来围绕一个点旋转一个顶点:
public Point2D.Double usingOriginAsRotationPoint(Point2D.Double vertex, Point2D.Double rotationPoint, double angle) {
double translatedToOriginX = vertex.x - rotationPoint.x;
double translatedToOriginY = vertex.y - rotationPoint.y;
double rotatedX = translatedToOriginX * Math.cos(angle) - translatedToOriginY * Math.sin(angle);
double rotatedY = translatedToOriginX * Math.sin(angle) + translatedToOriginY * Math.cos(angle);
double reverseTranslatedX = rotatedX + rotationPoint.x;
double reverseTranslatedY = rotatedY + rotationPoint.y;
return new Point2D.Double(reverseTranslatedX, reverseTranslatedY);
}
Let’s test this approach to rotate a vertex:
让我们测试一下这种旋转顶点的方法:
void givenRotationPoint_whenUseOrigin_thenRotateVertex() {
Point2D.Double vertex = new Point2D.Double(2.0, 2.0);
Point2D.Double rotationPoint = new Point2D.Double(0.0, 1.0);
double angle = Math.toRadians(45.0);
Point2D.Double rotatedVertex = VertexRotation.usingOriginAsRotationPoint(vertex, rotationPoint, angle);
assertEquals(0.707, rotatedVertex.getX(), 0.001);
assertEquals(3.121, rotatedVertex.getY(), 0.001);
}
4. Using the AffineTransform Class
4. 使用 AffineTransform 类
In this approach, we’ll leverage the AffineTransform class, which is used to perform geometric transformations like translations, scales, rotations, and flips.
在这种方法中,我们将利用 AffineTransform 类,该类用于执行几何变换,如平移、缩放、旋转和翻转。
We’ll first use the getRotateInstance() to create a rotation transformation matrix based on the specified angle and rotation point. Subsequently, we’ll use the transform() method to apply the transformation to the vertex and perform rotation. Let’s take a look at this approach:
我们将首先使用 getRotateInstance() 根据指定的角度和旋转点创建旋转变换矩阵。然后,我们将使用 transform() 方法将变换应用到顶点并执行旋转。让我们来看看这种方法:
public Point2D.Double usingAffineTransform(Point2D.Double vertex, Point2D.Double rotationPoint, double angle) {
AffineTransform affineTransform = AffineTransform.getRotateInstance(angle, rotationPoint.x, rotationPoint.y);
Point2D.Double rotatedVertex = new Point2D.Double();
affineTransform.transform(vertex, rotatedVertex);
return rotatedVertex;
}
Let’s test this approach to rotate a vertex:
让我们测试一下这种旋转顶点的方法:
void givenRotationPoint_whenUseAffineTransform_thenRotateVertex() {
Point2D.Double vertex = new Point2D.Double(2.0, 2.0);
Point2D.Double rotationPoint = new Point2D.Double(0.0, 1.0);
double angle = Math.toRadians(45.0);
Point2D.Double rotatedVertex = VertexRotation.usingAffineTransform(vertex, rotationPoint, angle);
assertEquals(0.707, rotatedVertex.getX(), 0.001);
assertEquals(3.121, rotatedVertex.getY(), 0.001);
}
5. Conclusion
5.结论
In this tutorial, we’ve discussed ways to rotate a vertex around a certain point.
在本教程中,我们讨论了围绕某个点旋转顶点的方法。
As always, the code used in the examples is available over on GitHub.
一如既往,示例中使用的代码可在 GitHub 上获取。