Rotate 2D polygon to _specified_ rotation

That’s exactly what I ended up going with! Thanks!

Here’s my code in case anyone else wants to do this same thing:

class Polygon
{
    private readonly Vector2[] ModelVertices;
    private Vector2 Position;
    private float currentAngle = 0.0f;

    public Vector2[] WorldVertices;

    /// <summary>
    /// Create a polygon defined by <paramref name="vertices"/>, centered around <paramref name="position"/>.
    /// </summary>
    /// <param name="vertices">An array of Vector2 positions defining the vertices of the polygon.</param>
    /// <param name="position">The position, in world space, around which the polygon should be centered.</param>
    public Polygon(Vector2[] vertices, Vector2 position)
    {
        Position = position;
        WorldVertices = new Vector2[vertices.Length];
        ModelVertices = new Vector2[vertices.Length];

        Vector2 center = CenterOfPolygon(vertices);

        //Cache the model vertices positioned adjusted to be around the origin
        for (int i = 0; i < vertices.Length; i++)
        {
            ModelVertices[i] = vertices[i] - center;
        }

        for (int i = 0; i < vertices.Length; i++)
        {
            WorldVertices[i] = vertices[i];
        }
    }

    public void Update()
    {
        //Rotate the polygon by 3.5 degrees every frame
        currentAngle += 3.5f;
        float angle = MathHelper.ToRadians(currentAngle);

        //Use the ModelVertices offsets to calculate new positions for the WorldVertices to be rendered
        //See https://en.wikipedia.org/wiki/Rotation_(mathematics)#Two_dimensions for the trig explanation
        for (int i = 0; i < WorldVertices.Length; i++)
        {
            WorldVertices[i].X = Position.X +
                                 ModelVertices[i].X * (float) Math.Cos(angle) +
                                 ModelVertices[i].Y * (float) Math.Sin(angle);

            WorldVertices[i].Y = Position.Y -
                                 ModelVertices[i].X * (float) Math.Sin(angle) +
                                 ModelVertices[i].Y * (float) Math.Cos(angle);
        }

        Position = Input.MousePosition();
    }

    /// <summary>
    /// Calculates the center of a polygon defined by <paramref name="vertices"/>
    /// </summary>
    /// <param name="vertices">An array of Vector2 positions defining the vertices of the polygon.</param>
    /// <returns>A Vector2 representing the world space position of the center of the given polygon.</returns>
    public static Vector2 CenterOfPolygon(Vector2[] vertices)
    {
        Vector2 sumCentre = Vector2.Zero;
        float sumWeight = 0.0f;

        for (int i = 0; i < vertices.Length; i++)
        {
            int prevIndex = (i - 1 + vertices.Length) % vertices.Length;
            int nextIndex = (i + 1) % vertices.Length;

            float weight = Vector2.Distance(vertices[i], vertices[prevIndex]) +
                           Vector2.Distance(vertices[i], vertices[nextIndex]);

            sumCentre += vertices[i] * weight;
            sumWeight += weight;
        }

        return sumCentre / sumWeight;
    }
}
1 Like