Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

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.

2. Understanding the Problem Statement

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:

Rotating a vertex around a point

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.

3. Using Origin as the Rotation Point

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.

3.1. Rotate a Point P Around the Origin

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:

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.

3.2. Rotation Around a Given Point

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.

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.

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

In this approach, we’ll leverage the AffineTransform class, which is used to perform geometric transformations like translations, scales, rotations, and flips.

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:

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

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.

Course – LS – All

Get started with Spring and Spring Boot, through the Learn Spring course:

>> CHECK OUT THE COURSE
res – REST with Spring (eBook) (everywhere)
Comments are open for 30 days after publishing a post. For any issues past this date, use the Contact form on the site.