Q:

Не совсем корректный подсчет координат треугольника

Есть такая задача:

Описать  класс,  представляющий  треугольник.  Предусмотреть методы 
  для  создания  объектов,  перемещения  на  плоскости,  изменения
  размеров и вращения на заданный угол. Описать свойства для получения
  состояния объекта. При невозможности построения треугольника должны
  "выбрасываться" исключения. Написать  программу,  демонстрирующую  все
  разработанные элементы класса.

У меня почти все готово. Класс описан, все методы готовы, за исключением последнего. Он тоже описан, но работает не совсем корректно
В структуре программы имеется два класса: Point и Triangle. Triangle описывается тремя точками(класс Point)
Ниже предоставляю кусок кода, этого самого метода вращения треугольника. В математике я не силен, нашел в интернете как это сделать(умножение каждой точки треугольника на матрицу поворота) и нашел пример кода, поэтому мог допустить ошибки.
public void Rotate(double rad, Point a, Point b, Point c)
        {
            a = new Point((int)((double)a.point_X * Math.Cos(rad) - (double)a.point_Y * Math.Sin(rad)), (int)((double)a.point_X * Math.Sin(rad) + (double)a.point_Y * Math.Cos(rad)));
            b = new Point((int)((double)b.point_X * Math.Cos(rad) - (double)b.point_Y * Math.Sin(rad)), (int)((double)b.point_X * Math.Sin(rad) + (double)b.point_Y * Math.Cos(rad)));
            c = new Point((int)((double)c.point_X * Math.Cos(rad) - (double)c.point_Y * Math.Sin(rad)), (int)((double)c.point_X * Math.Sin(rad) + (double)c.point_Y * Math.Cos(rad)));
            A = a;
            B = b;
            C = c;
        }

Этот код частично выполняет свою задачу, выглядит это примерно так:

На фото видно, что треугольник повернулся на те самые 90 градусов, но сам треугольник изменил свои координаты и размеры.

Если вопрос проблема описана плохо или требуется весь код работы, сообщите пожалуйста в комментариях предоставлю его на pastebin. Заранее спасибо:)

A:

У вас некорректная архитектура: вам нужен не треугольник, а полигон. Все алгоритмы такие же, только вместо обработки 3-х координат - цикл. Вот классы:
public enum AngleUnit
{
    Degree, // 360°
    Radian, // 2*π
    Grad, // 400ᵍ
    Turn // 1 turn
}

public readonly struct Angle : IEquitable<Angle>
{
    public double Value { get; }
    public AngleUnit Unit { get; }

    // ...

    public double ToRadians() { /*...*/ }

    // ...
}

public struct Matrix : IEquitable<Matrix>
{
    public double M11 { get; set; }
    public double M12 { get; set; }
    public double M21 { get; set; }
    public double M22 { get; set; }
    public double OffsetX { get; set; }
    public double OffsetY { get; set; }

    // ...
}

public readonly struct Vector2 : IEquitable<Vector2>
{
    public static readonly Vector2 Zero = new Vector2();

    public double X { get; }
    public double Y { get; }
    public double Magnitude => Math.Sqrt(X * X + Y * Y);
    public double PhaseInRadians => Math.Atan2(Y, X);
    public Angle Phase => Angle.FromRadians(PhaseInRadians);

    // ...

    public Vector2 Transform(ref Matrix matrix) =>
        (X * matrix.M11 + Y * matrix.M21 + matrix.OffsetX,
        X * matrix.M12 + Y * matrix.M22 + matrix.OffsetY);
    public Vecto2 RotateAt(Vector2 origin, Angle angle) =>
        new Vertor2(Magnitude, Phase + angle); // возможно, не самый лучший алгоритм
    public Vector2 Rotate(Angle angle) => RotateAt(Zero, angle);

    // ...

    public static implicit operator (double X, double Y)(Vector2 vector)
    {
        vector.Deconstruct(out var x, out var y);

        return (x, y);
    }
}

public readonly struct Rect : IEquitable<Rect>
{
    // ...
}

public class Polygon
{
    public Memory<Vector2> Points { get; }
    public int SideCount => Points.Length;
    public Rect Bounds => ComputeBounds(Points.Span);
    public Vector2 Center => Bounds.Center;

    public Polygon(Memory<Vector2> points)
    {
        if (points.Length < 3) throw /*...*/;

        Points = points;
    }

    static Rect ComputeBounds(ReadOnlySpan<Vector2> points)
    {
        var l = points[0].X;
        var t = points[0].Y;
        var r = l;
        var b = t;

        foreach (var point in points)
        {
            if (point.X < l)
                l = point.X;
            else if (point.X > r)
                r = point.X;
            if (point.Y < t)
                t = point.Y;
            else if (point.Y > b)
                b = point.Y;
        }

        return Rect.FromLtrb(l, t, r, b);
    }
    public void Transform(ref Matrix matrix)
    {
        for (var i = 0; i < SideCount; i++)
            points[i] = points[i].Transform(ref matrix);
    }
    public void RotateAt(Vector2 origin, Angle angle)
    {
        var matrix = new Matrix();
        matrix.Translate(origin);
        matrix.Rotate(origin);

        Transform(ref matrix);
    }
    public void Rotate(Angle angle) => RotateAt(Center, angle);
}

void Run()
{
    var points = new Vector2[]
    {
        (0.0, 0.0),
        (4.0, 0.0),
        (2.0, 2.0)
    };
    var triangle = new Polygon(points.AsMemory());

    PrintPoints(points.AsSpan());

    triangle.RotateAt(Vector2.Zero, Angle.FromDegree(-90.0));

    PrintPoints(points.AsSpan()); // т. к. мы используем `Memory`, то можно и так
}
void PrintPoints(ReadOnlySpan<Vector2> points)
{
    Console.WriteLine("Points: ");

    foreach (var point in points)
        Console.WriteLine($"    {point}"); // тут лучше использовать 'ValueModel' (ссылка #1, ссылка #2)
}

Ссылка #1: "Stackalloc: забытая команда C#"
Ссылка #2: "Span: новый тип данных .NET"

