using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace _2DTest
{

    public class Obstacle : GameObject
    {
        // Konstruktor für die Hindernisse
        public Obstacle(PointF position, List<PointF> localPoints)
        {
            Transform.LocalPosition = position;
            MeshComponent meshComponent = new MeshComponent(localPoints, this);
            AddComponent(meshComponent);
        }
    }

    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;
        private List<Obstacle> obstacles;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            rootObject.Transform.MoveInDirection(100f);
            rootObject.Update();

            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);
            childObject.Update();

            MeshComponent rootMesh = new MeshComponent(new List<PointF>
            {
                new PointF(-25, -45),
                new PointF(-25, 25),
                new PointF(25, 25),
                new PointF(25, -75)
            }, rootObject);

            rootObject.AddComponent(rootMesh);

            MeshComponent childMesh = new MeshComponent(new List<PointF>
            {
                new PointF(-15, -15),
                new PointF(-15, 15),
                new PointF(15, 15),
                new PointF(15, -15)
            }, childObject);

            childObject.AddComponent(childMesh);

            // Initialize obstacles
            obstacles = new List<Obstacle>();

            obstacles.Add(new Obstacle(new PointF(200, 200), new List<PointF>
            {
                new PointF(-50, -50),
                new PointF(-50, 50),
                new PointF(50, 50),
                new PointF(50, -50)
            }));
            obstacles.Add(new Obstacle(new PointF(400, 300), new List<PointF>
            {
                new PointF(-40, -40),
                new PointF(-40, 40),
                new PointF(40, 40),
                new PointF(40, -40)
            }));

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw game objects
            rootObject.Draw(e.Graphics);
            childObject.Draw(e.Graphics);

            foreach (var obstacle in obstacles)
            {
                RectangleF rect1 = GetBoundingBox(obstacle);
                e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(rect1));

                obstacle.Draw(e.Graphics);
            }

        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.Rotate(-5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.Rotate(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    rootObject.Transform.RotateChildren(5f); // Rotate children around the root
                    break;
                case Keys.S:
                    rootObject.Transform.ScaleGlobal(1.1f); // Scale up by 10% globally
                    break;
                case Keys.D:
                    rootObject.Transform.ScaleGlobal(1 / 1.1f); // Scale down by 10% globally
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();
            childObject.Update();

            // Get the global points of the rootObject and childObject
            List<PointF> rootPoints = rootObject.GetGlobalPoints(); // GetGlobalPoints(rootObject);
            List<PointF> childPoints = childObject.GetGlobalPoints(); // GetGlobalPoints(childObject);

            // Check for collisions with obstacles
            foreach (var obstacle in obstacles)
            {
                obstacle.Update();

                //MeshComponent obstacleMesh = obstacle.GetComponent<MeshComponent>();

                List<PointF> obstaclePoints = obstacle.GetGlobalPoints(); //GetGlobalPoints(obstacle);

                //if (CheckCollision(rootObject, obstacle))
                if (Collide(rootPoints.ToArray<PointF>(), obstaclePoints.ToArray<PointF>()))
                {
                    // Handle collision
                    Console.WriteLine(DateTime.Now.ToString("HH:MM:ss") + " Collision with obstacle!");
                    // Implement collision handling logic here
                }
            }

            // Redraw the form
            this.Invalidate();
        }

        private bool CheckCollision(GameObject obj1, GameObject obj2)
        {
            // Implement collision detection logic here
            // For simplicity, let's assume all objects are rectangles and check if their bounding boxes intersect
            RectangleF rect1 = GetBoundingBox(obj1);
            RectangleF rect2 = GetBoundingBox(obj2);
            return rect1.IntersectsWith(rect2);
        }

        public bool Collide(PointF[] first, PointF[] second)
        {
            List<PointF> self = first.ToList();
            List<PointF> otherList = second.ToList();

            return PolygonIntersectsPolygon(self, otherList) || PolygonIntersectsPolygon(otherList, self);
        }

        public bool PolygonIntersectsPolygon(List<PointF> polygonA, List<PointF> polygonB)
        {
            int countA = polygonA.Count;
            int countB = polygonB.Count;

            for (int i = 0; i < countA; i++)
            {
                PointF p1 = polygonA[i];
                PointF p2 = polygonA[(i + 1) % countA];

                if (LineIntersectsPolygon(p1, p2, polygonB))
                {
                    return true;
                }
            }

            return false;
        }

        public bool LineIntersectsPolygon(PointF p1, PointF p2, List<PointF> polygon)
        {
            int count = polygon.Count;

            for (int i = 0; i < count; i++)
            {
                PointF q1 = polygon[i];
                PointF q2 = polygon[(i + 1) % count];

                if (LineIntersectsLine(p1, p2, q1, q2))
                {
                    return true;
                }
            }

            return false;
        }

        public bool LineIntersectsLine(PointF p1, PointF p2, PointF q1, PointF q2)
        {
            int o1 = Orientation(p1, p2, q1);
            int o2 = Orientation(p1, p2, q2);
            int o3 = Orientation(q1, q2, p1);
            int o4 = Orientation(q1, q2, p2);

            if (o1 != o2 && o3 != o4)
            {
                return true;
            }

            if (o1 == 0 && OnSegment(p1, q1, p2)) return true;
            if (o2 == 0 && OnSegment(p1, q2, p2)) return true;
            if (o3 == 0 && OnSegment(q1, p1, q2)) return true;
            if (o4 == 0 && OnSegment(q1, p2, q2)) return true;

            return false;
        }

        public int Orientation(PointF p, PointF q, PointF r)
        {
            float val = (q.Y - p.Y) * (r.X - q.X) - (q.X - p.X) * (r.Y - q.Y);
            if (val == 0) return 0;
            return (val > 0) ? 1 : 2;
        }

        public bool OnSegment(PointF p, PointF q, PointF r)
        {
            return q.X <= Math.Max(p.X, r.X) && q.X >= Math.Min(p.X, r.X) &&
                   q.Y <= Math.Max(p.Y, r.Y) && q.Y >= Math.Min(p.Y, r.Y);
        }


        // Method to get the bounding box of a game object
        private RectangleF GetBoundingBox(GameObject obj)
        {
            // Initialize min and max points with extreme values
            PointF minPoint = new PointF(float.MaxValue, float.MaxValue);
            PointF maxPoint = new PointF(float.MinValue, float.MinValue);

            // Iterate through all mesh components of the object
            foreach (var component in obj.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    // Iterate through all local points of the mesh
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        // Transform local point to global point
                        PointF globalPoint = TransformPoint(localPoint, obj.Transform);

                        // Update min and max points based on the global point
                        minPoint.X = Math.Min(minPoint.X, globalPoint.X);
                        minPoint.Y = Math.Min(minPoint.Y, globalPoint.Y);
                        maxPoint.X = Math.Max(maxPoint.X, globalPoint.X);
                        maxPoint.Y = Math.Max(maxPoint.Y, globalPoint.Y);
                    }
                }
            }

            // Calculate the size of the bounding box
            SizeF size = new SizeF(maxPoint.X - minPoint.X, maxPoint.Y - minPoint.Y);

            // Calculate the position of the bounding box (bottom-left corner)
            PointF position = new PointF(minPoint.X, minPoint.Y);

            return new RectangleF(position, size);
        }

        private List<PointF> GetGlobalPoints1(GameObject gameObject)
        {
            List<PointF> globalPoints = new List<PointF>();

            foreach (var component in gameObject.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        PointF globalPoint = TransformPoint(localPoint, gameObject.Transform);
                        globalPoints.Add(globalPoint);
                    }
                }
            }

            return globalPoints;
        }

        private List<PointF> GetGlobalPoints(GameObject gameObject)
        {
            List<PointF> globalPoints = new List<PointF>();

            foreach (var component in gameObject.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        // Apply global scale
                        PointF scaledPoint = new PointF(localPoint.X * gameObject.Transform.Scale, localPoint.Y * gameObject.Transform.Scale);

                        // Transform scaled point to global point
                        PointF globalPoint = TransformPoint(scaledPoint, gameObject.Transform);
                        globalPoints.Add(globalPoint);
                    }
                }
            }

            return globalPoints;
        }

        // Method to transform a local point to global point using the given transform
        private PointF TransformPoint(PointF point, TransformComponent transform)
        {
            // Rotate the point around the origin
            PointF rotatedPoint = RotatePoint(point, PointF.Empty, transform.GlobalRotation);

            // Translate the rotated point based on the global position
            PointF globalPoint = new PointF(rotatedPoint.X + transform.GlobalPosition.X, rotatedPoint.Y + transform.GlobalPosition.Y);

            return globalPoint;
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }


    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> Children { get; private set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
            Children = new List<TransformComponent>();
        }

        public void AddChild(TransformComponent child)
        {
            child.Parent = this;
            Children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            child.Parent = null;
            Children.Remove(child);
        }

        public TransformComponent Parent { get; private set; }

        public void UpdateGlobalTransform()
        {
            // Update global position and rotation
            if (Parent != null)
            {
                // Calculate global rotation
                GlobalRotation = LocalRotation + Parent.GlobalRotation;

                // Calculate global position
                PointF rotatedPosition = RotatePoint(LocalPosition, PointF.Empty, Parent.GlobalRotation);
                GlobalPosition = new PointF(rotatedPosition.X + Parent.GlobalPosition.X, rotatedPosition.Y + Parent.GlobalPosition.Y);
            }
            else
            {
                GlobalPosition = LocalPosition;
                GlobalRotation = LocalRotation;
            }

            // Update children transforms
            foreach (var child in Children)
            {
                child.UpdateGlobalTransform();
            }
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void RotateChildren(float angleInDegrees)
        {
            foreach (var child in Children)
            {
                child.LocalRotation += angleInDegrees;
            }
        }

        public void MoveInDirection(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        private void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveGlobal(float dx, float dy)
        {
            // Move globally by adding the deltas to the global position
            GlobalPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);
        }

        public void RotateGlobal(float angleInDegrees)
        {
            // Rotate globally by adding the angle to the global rotation
            GlobalRotation += angleInDegrees;
        }

        public void ScaleGlobal(float factor)
        {
            // Scale globally by multiplying the scale factor
            Scale *= factor;
        }

    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }
        public List<Component> components;

        public GameObject()
        {
            Transform = new TransformComponent();
            components = new List<Component>();
        }

        public void AddChild(GameObject child)
        {
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalTransform();
        }

        public void Draw(Graphics graphics)
        {
            // Draw each component
            foreach (var component in components)
            {
                component.Draw(graphics);
            }
        }

        public void AddComponent(Component component)
        {
            components.Add(component);
        }

        public void RemoveComponent(Component component)
        {
            components.Remove(component);
        }

        public T GetComponent<T>() where T : Component
        {
            // Durchsuchen Sie die Liste der Komponenten und geben Sie die erste Instanz des Typs T zurück, die gefunden wird
            foreach (var component in components)
            {
                if (component is T typedComponent)
                {
                    return typedComponent;
                }
            }

            // Wenn keine Instanz des Typs T gefunden wurde, geben Sie null zurück
            return null;
        }

        public List<PointF> GetGlobalPoints()
        {
            List<PointF> globalPoints = new List<PointF>();

            foreach (var component in components)
            {
                if (component is MeshComponent meshComponent)
                {
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        // Apply global scale
                        PointF scaledPoint = new PointF(localPoint.X * Transform.Scale, localPoint.Y * Transform.Scale);

                        // Transform scaled point to global point
                        PointF globalPoint = TransformPoint(scaledPoint, Transform);
                        globalPoints.Add(globalPoint);
                    }
                }
            }

            return globalPoints;
        }
        private PointF TransformPoint(PointF point, TransformComponent transform)
        {
            // Rotate the point around the origin
            PointF rotatedPoint = RotatePoint(point, PointF.Empty, transform.GlobalRotation);

            // Translate the rotated point based on the global position
            PointF globalPoint = new PointF(rotatedPoint.X + transform.GlobalPosition.X, rotatedPoint.Y + transform.GlobalPosition.Y);

            return globalPoint;
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }


    }

    public abstract class Component
    {
        public abstract void Draw(Graphics graphics);
    }

    public class MeshComponent : Component
    {
        public List<PointF> localPoints;
        private GameObject gameObject;

        public MeshComponent(List<PointF> localPoints, GameObject gameObject)
        {
            this.localPoints = localPoints;
            this.gameObject = gameObject;
        }

        public override void Draw(Graphics graphics)
        {
            // Draw the mesh
            if (localPoints.Count < 3)
                return; // Cannot draw a mesh with less than 3 points

            // Transform local points to global points
            PointF[] globalPoints = new PointF[localPoints.Count];
            for (int i = 0; i < localPoints.Count; i++)
            {
                // Apply global scale
                PointF scaledPoint = new PointF(localPoints[i].X * gameObject.Transform.Scale, localPoints[i].Y * gameObject.Transform.Scale);

                // Rotate and translate the scaled point to global coordinates
                PointF rotatedPoint = RotatePoint(scaledPoint, PointF.Empty, gameObject.Transform.GlobalRotation);
                PointF globalPoint = new PointF(rotatedPoint.X + gameObject.Transform.GlobalPosition.X,
                                                 rotatedPoint.Y + gameObject.Transform.GlobalPosition.Y);
                globalPoints[i] = globalPoint;
            }

            graphics.DrawPolygon(Pens.Black, globalPoints);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

    }

}












/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace _2DTest
{

    public class Obstacle : GameObject
    {
        // Konstruktor für die Hindernisse
        public Obstacle(PointF position, List<PointF> localPoints)
        {
            Transform.LocalPosition = position;
            MeshComponent meshComponent = new MeshComponent(localPoints, this);
            AddComponent(meshComponent);
        }
    }

    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;
        private List<Obstacle> obstacles;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            rootObject.Transform.MoveInDirection(100f);
            rootObject.Update();

            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);
            childObject.Update();

            MeshComponent rootMesh = new MeshComponent(new List<PointF>
            {
                new PointF(-25, -45),
                new PointF(-25, 25),
                new PointF(25, 25),
                new PointF(25, -75)
            }, rootObject);

            rootObject.AddComponent(rootMesh);

            MeshComponent childMesh = new MeshComponent(new List<PointF>
            {
                new PointF(-15, -15),
                new PointF(-15, 15),
                new PointF(15, 15),
                new PointF(15, -15)
            }, childObject);

            childObject.AddComponent(childMesh);

            // Initialize obstacles
            obstacles = new List<Obstacle>();

            obstacles.Add(new Obstacle(new PointF(200, 200), new List<PointF>
            {
                new PointF(-50, -50),
                new PointF(-50, 50),
                new PointF(50, 50),
                new PointF(50, -50)
            }));
            obstacles.Add(new Obstacle(new PointF(400, 300), new List<PointF>
            {
                new PointF(-40, -40),
                new PointF(-40, 40),
                new PointF(40, 40),
                new PointF(40, -40)
            }));

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw game objects
            rootObject.Draw(e.Graphics);
            childObject.Draw(e.Graphics);

            foreach (var obstacle in obstacles)
            {
                RectangleF rect1 = GetBoundingBox(obstacle);
                e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(rect1));

                obstacle.Draw(e.Graphics);
            }

        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.Rotate(-5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.Rotate(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    rootObject.Transform.RotateChildren(5f); // Rotate children around the root
                    break;
                case Keys.S:
                    rootObject.Transform.ScaleGlobal(1.1f); // Scale up by 10% globally
                    break;
                case Keys.D:
                    rootObject.Transform.ScaleGlobal(1 / 1.1f); // Scale down by 10% globally
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();
            childObject.Update();

            // Get the global points of the rootObject and childObject
            List<PointF> rootPoints = GetGlobalPoints(rootObject);
            List<PointF> childPoints = GetGlobalPoints(childObject);

            // Check for collisions with obstacles
            foreach (var obstacle in obstacles)
            {
                obstacle.Update();

                List<PointF> obstaclePoints = GetGlobalPoints(obstacle);

                //if (CheckCollision(rootObject, obstacle))
                if (Collide(rootPoints.ToArray<PointF>(), obstaclePoints.ToArray<PointF>()))
                {
                    // Handle collision
                    Console.WriteLine(DateTime.Now.ToString("HH:MM:ss") + " Collision with obstacle!");
                    // Implement collision handling logic here
                }
            }

            // Redraw the form
            this.Invalidate();
        }

        private bool CheckCollision(GameObject obj1, GameObject obj2)
        {
            // Implement collision detection logic here
            // For simplicity, let's assume all objects are rectangles and check if their bounding boxes intersect
            RectangleF rect1 = GetBoundingBox(obj1);
            RectangleF rect2 = GetBoundingBox(obj2);
            return rect1.IntersectsWith(rect2);
        }

        public bool Collide(PointF[] first, PointF[] second)
        {
            List<PointF> self = first.ToList();
            List<PointF> otherList = second.ToList();

            return PolygonIntersectsPolygon(self, otherList) || PolygonIntersectsPolygon(otherList, self);
        }

        public bool PolygonIntersectsPolygon(List<PointF> polygonA, List<PointF> polygonB)
        {
            int countA = polygonA.Count;
            int countB = polygonB.Count;

            for (int i = 0; i < countA; i++)
            {
                PointF p1 = polygonA[i];
                PointF p2 = polygonA[(i + 1) % countA];

                if (LineIntersectsPolygon(p1, p2, polygonB))
                {
                    return true;
                }
            }

            return false;
        }

        public bool LineIntersectsPolygon(PointF p1, PointF p2, List<PointF> polygon)
        {
            int count = polygon.Count;

            for (int i = 0; i < count; i++)
            {
                PointF q1 = polygon[i];
                PointF q2 = polygon[(i + 1) % count];

                if (LineIntersectsLine(p1, p2, q1, q2))
                {
                    return true;
                }
            }

            return false;
        }

        public bool LineIntersectsLine(PointF p1, PointF p2, PointF q1, PointF q2)
        {
            int o1 = Orientation(p1, p2, q1);
            int o2 = Orientation(p1, p2, q2);
            int o3 = Orientation(q1, q2, p1);
            int o4 = Orientation(q1, q2, p2);

            if (o1 != o2 && o3 != o4)
            {
                return true;
            }

            if (o1 == 0 && OnSegment(p1, q1, p2)) return true;
            if (o2 == 0 && OnSegment(p1, q2, p2)) return true;
            if (o3 == 0 && OnSegment(q1, p1, q2)) return true;
            if (o4 == 0 && OnSegment(q1, p2, q2)) return true;

            return false;
        }

        public int Orientation(PointF p, PointF q, PointF r)
        {
            float val = (q.Y - p.Y) * (r.X - q.X) - (q.X - p.X) * (r.Y - q.Y);
            if (val == 0) return 0;
            return (val > 0) ? 1 : 2;
        }

        public bool OnSegment(PointF p, PointF q, PointF r)
        {
            return q.X <= Math.Max(p.X, r.X) && q.X >= Math.Min(p.X, r.X) &&
                   q.Y <= Math.Max(p.Y, r.Y) && q.Y >= Math.Min(p.Y, r.Y);
        }


        // Method to get the bounding box of a game object
        private RectangleF GetBoundingBox(GameObject obj)
        {
            // Initialize min and max points with extreme values
            PointF minPoint = new PointF(float.MaxValue, float.MaxValue);
            PointF maxPoint = new PointF(float.MinValue, float.MinValue);

            // Iterate through all mesh components of the object
            foreach (var component in obj.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    // Iterate through all local points of the mesh
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        // Transform local point to global point
                        PointF globalPoint = TransformPoint(localPoint, obj.Transform);

                        // Update min and max points based on the global point
                        minPoint.X = Math.Min(minPoint.X, globalPoint.X);
                        minPoint.Y = Math.Min(minPoint.Y, globalPoint.Y);
                        maxPoint.X = Math.Max(maxPoint.X, globalPoint.X);
                        maxPoint.Y = Math.Max(maxPoint.Y, globalPoint.Y);
                    }
                }
            }

            // Calculate the size of the bounding box
            SizeF size = new SizeF(maxPoint.X - minPoint.X, maxPoint.Y - minPoint.Y);

            // Calculate the position of the bounding box (bottom-left corner)
            PointF position = new PointF(minPoint.X, minPoint.Y);

            return new RectangleF(position, size);
        }

        private List<PointF> GetGlobalPoints1(GameObject gameObject)
        {
            List<PointF> globalPoints = new List<PointF>();

            foreach (var component in gameObject.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        PointF globalPoint = TransformPoint(localPoint, gameObject.Transform);
                        globalPoints.Add(globalPoint);
                    }
                }
            }

            return globalPoints;
        }

        private List<PointF> GetGlobalPoints(GameObject gameObject)
        {
            List<PointF> globalPoints = new List<PointF>();

            foreach (var component in gameObject.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        // Apply global scale
                        PointF scaledPoint = new PointF(localPoint.X * gameObject.Transform.Scale, localPoint.Y * gameObject.Transform.Scale);

                        // Transform scaled point to global point
                        PointF globalPoint = TransformPoint(scaledPoint, gameObject.Transform);
                        globalPoints.Add(globalPoint);
                    }
                }
            }

            return globalPoints;
        }

        // Method to transform a local point to global point using the given transform
        private PointF TransformPoint(PointF point, TransformComponent transform)
        {
            // Rotate the point around the origin
            PointF rotatedPoint = RotatePoint(point, PointF.Empty, transform.GlobalRotation);

            // Translate the rotated point based on the global position
            PointF globalPoint = new PointF(rotatedPoint.X + transform.GlobalPosition.X, rotatedPoint.Y + transform.GlobalPosition.Y);

            return globalPoint;
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }


    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> Children { get; private set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
            Children = new List<TransformComponent>();
        }

        public void AddChild(TransformComponent child)
        {
            child.Parent = this;
            Children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            child.Parent = null;
            Children.Remove(child);
        }

        public TransformComponent Parent { get; private set; }

        public void UpdateGlobalTransform()
        {
            // Update global position and rotation
            if (Parent != null)
            {
                // Calculate global rotation
                GlobalRotation = LocalRotation + Parent.GlobalRotation;

                // Calculate global position
                PointF rotatedPosition = RotatePoint(LocalPosition, PointF.Empty, Parent.GlobalRotation);
                GlobalPosition = new PointF(rotatedPosition.X + Parent.GlobalPosition.X, rotatedPosition.Y + Parent.GlobalPosition.Y);
            }
            else
            {
                GlobalPosition = LocalPosition;
                GlobalRotation = LocalRotation;
            }

            // Update children transforms
            foreach (var child in Children)
            {
                child.UpdateGlobalTransform();
            }
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void RotateChildren(float angleInDegrees)
        {
            foreach (var child in Children)
            {
                child.LocalRotation += angleInDegrees;
            }
        }

        public void MoveInDirection(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        private void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveGlobal(float dx, float dy)
        {
            // Move globally by adding the deltas to the global position
            GlobalPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);
        }

        public void RotateGlobal(float angleInDegrees)
        {
            // Rotate globally by adding the angle to the global rotation
            GlobalRotation += angleInDegrees;
        }

        public void ScaleGlobal(float factor)
        {
            // Scale globally by multiplying the scale factor
            Scale *= factor;
        }

    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }
        public List<Component> components;

        public GameObject()
        {
            Transform = new TransformComponent();
            components = new List<Component>();
        }

        public void AddChild(GameObject child)
        {
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalTransform();
        }

        public void Draw(Graphics graphics)
        {
            // Draw each component
            foreach (var component in components)
            {
                component.Draw(graphics);
            }
        }

        public void AddComponent(Component component)
        {
            components.Add(component);
        }

        public void RemoveComponent(Component component)
        {
            components.Remove(component);
        }
    }

    public abstract class Component
    {
        public abstract void Draw(Graphics graphics);
    }

    public class MeshComponent : Component
    {
        public List<PointF> localPoints;
        private GameObject gameObject;

        public MeshComponent(List<PointF> localPoints, GameObject gameObject)
        {
            this.localPoints = localPoints;
            this.gameObject = gameObject;
        }

        public override void Draw(Graphics graphics)
        {
            // Draw the mesh
            if (localPoints.Count < 3)
                return; // Cannot draw a mesh with less than 3 points

            // Transform local points to global points
            PointF[] globalPoints = new PointF[localPoints.Count];
            for (int i = 0; i < localPoints.Count; i++)
            {
                // Apply global scale
                PointF scaledPoint = new PointF(localPoints[i].X * gameObject.Transform.Scale, localPoints[i].Y * gameObject.Transform.Scale);

                // Rotate and translate the scaled point to global coordinates
                PointF rotatedPoint = RotatePoint(scaledPoint, PointF.Empty, gameObject.Transform.GlobalRotation);
                PointF globalPoint = new PointF(rotatedPoint.X + gameObject.Transform.GlobalPosition.X,
                                                 rotatedPoint.Y + gameObject.Transform.GlobalPosition.Y);
                globalPoints[i] = globalPoint;
            }

            graphics.DrawPolygon(Pens.Black, globalPoints);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

    }
}
*/









/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Windows.Forms;

namespace _2DTest
{

    public class Obstacle : GameObject
    {
        // Konstruktor für die Hindernisse
        public Obstacle(PointF position, List<PointF> localPoints)
        {
            Transform.LocalPosition = position;
            MeshComponent meshComponent = new MeshComponent(localPoints, this);
            AddComponent(meshComponent);
        }
    }

    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;
        private List<Obstacle> obstacles;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            rootObject.Transform.MoveInDirection(100f);
            rootObject.Update();

            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);
            childObject.Update();

            MeshComponent rootMesh = new MeshComponent(new List<PointF>
        {
            new PointF(-25, -45),
            new PointF(-25, 25),
            new PointF(25, 25),
            new PointF(25, -75)
        }, rootObject);

            rootObject.AddComponent(rootMesh);

            MeshComponent childMesh = new MeshComponent(new List<PointF>
        {
            new PointF(-15, -15),
            new PointF(-15, 15),
            new PointF(15, 15),
            new PointF(15, -15)
        }, childObject);

            childObject.AddComponent(childMesh);

            // Initialize obstacles
            obstacles = new List<Obstacle>();

            obstacles.Add(new Obstacle(new PointF(200, 200), new List<PointF>
        {
            new PointF(-50, -50),
            new PointF(-50, 50),
            new PointF(50, 50),
            new PointF(50, -50)
        }));
            obstacles.Add(new Obstacle(new PointF(400, 300), new List<PointF>
        {
            new PointF(-40, -40),
            new PointF(-40, 40),
            new PointF(40, 40),
            new PointF(40, -40)
        }));

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw game objects
            rootObject.Draw(e.Graphics);
            childObject.Draw(e.Graphics);

            foreach (var obstacle in obstacles)
            {
                RectangleF rect1 = GetBoundingBox(obstacle);
                e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(rect1));

                obstacle.Draw(e.Graphics);
            }

        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.Rotate(-5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.Rotate(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    rootObject.Transform.RotateChildren(5f); // Rotate children around the root
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();
            childObject.Update();

            // Get the global points of the rootObject and childObject
            List<PointF> rootPoints = GetGlobalPoints(rootObject);
            List<PointF> childPoints = GetGlobalPoints(childObject);

            // Check for collisions with obstacles
            foreach (var obstacle in obstacles)
            {
                obstacle.Update();

                List<PointF> obstaclePoints = GetGlobalPoints(obstacle);

                //if (CheckCollision(rootObject, obstacle))
                if (Collide(rootPoints.ToArray<PointF>(), obstaclePoints.ToArray<PointF>()))
                {
                    // Handle collision
                    Console.WriteLine(DateTime.Now.ToString("HH:MM:ss") + " Collision with obstacle!");
                    // Implement collision handling logic here
                }
            }

            // Redraw the form
            this.Invalidate();
        }

        private bool CheckCollision(GameObject obj1, GameObject obj2)
        {
            // Implement collision detection logic here
            // For simplicity, let's assume all objects are rectangles and check if their bounding boxes intersect
            RectangleF rect1 = GetBoundingBox(obj1);
            RectangleF rect2 = GetBoundingBox(obj2);
            return rect1.IntersectsWith(rect2);
        }

        public bool Collide(PointF[] first, PointF[] second)
        {
            List<PointF> self = first.ToList();
            List<PointF> otherList = second.ToList();

            return PolygonIntersectsPolygon(self, otherList) || PolygonIntersectsPolygon(otherList, self);
        }

        public bool PolygonIntersectsPolygon(List<PointF> polygonA, List<PointF> polygonB)
        {
            int countA = polygonA.Count;
            int countB = polygonB.Count;

            for (int i = 0; i < countA; i++)
            {
                PointF p1 = polygonA[i];
                PointF p2 = polygonA[(i + 1) % countA];

                if (LineIntersectsPolygon(p1, p2, polygonB))
                {
                    return true;
                }
            }

            return false;
        }

        public bool LineIntersectsPolygon(PointF p1, PointF p2, List<PointF> polygon)
        {
            int count = polygon.Count;

            for (int i = 0; i < count; i++)
            {
                PointF q1 = polygon[i];
                PointF q2 = polygon[(i + 1) % count];

                if (LineIntersectsLine(p1, p2, q1, q2))
                {
                    return true;
                }
            }

            return false;
        }

        public bool LineIntersectsLine(PointF p1, PointF p2, PointF q1, PointF q2)
        {
            int o1 = Orientation(p1, p2, q1);
            int o2 = Orientation(p1, p2, q2);
            int o3 = Orientation(q1, q2, p1);
            int o4 = Orientation(q1, q2, p2);

            if (o1 != o2 && o3 != o4)
            {
                return true;
            }

            if (o1 == 0 && OnSegment(p1, q1, p2)) return true;
            if (o2 == 0 && OnSegment(p1, q2, p2)) return true;
            if (o3 == 0 && OnSegment(q1, p1, q2)) return true;
            if (o4 == 0 && OnSegment(q1, p2, q2)) return true;

            return false;
        }

        public int Orientation(PointF p, PointF q, PointF r)
        {
            float val = (q.Y - p.Y) * (r.X - q.X) - (q.X - p.X) * (r.Y - q.Y);
            if (val == 0) return 0;
            return (val > 0) ? 1 : 2;
        }

        public bool OnSegment(PointF p, PointF q, PointF r)
        {
            return q.X <= Math.Max(p.X, r.X) && q.X >= Math.Min(p.X, r.X) &&
                   q.Y <= Math.Max(p.Y, r.Y) && q.Y >= Math.Min(p.Y, r.Y);
        }


        // Method to get the bounding box of a game object
        private RectangleF GetBoundingBox(GameObject obj)
        {
            // Initialize min and max points with extreme values
            PointF minPoint = new PointF(float.MaxValue, float.MaxValue);
            PointF maxPoint = new PointF(float.MinValue, float.MinValue);

            // Iterate through all mesh components of the object
            foreach (var component in obj.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    // Iterate through all local points of the mesh
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        // Transform local point to global point
                        PointF globalPoint = TransformPoint(localPoint, obj.Transform);

                        // Update min and max points based on the global point
                        minPoint.X = Math.Min(minPoint.X, globalPoint.X);
                        minPoint.Y = Math.Min(minPoint.Y, globalPoint.Y);
                        maxPoint.X = Math.Max(maxPoint.X, globalPoint.X);
                        maxPoint.Y = Math.Max(maxPoint.Y, globalPoint.Y);
                    }
                }
            }

            // Calculate the size of the bounding box
            SizeF size = new SizeF(maxPoint.X - minPoint.X, maxPoint.Y - minPoint.Y);

            // Calculate the position of the bounding box (bottom-left corner)
            PointF position = new PointF(minPoint.X, minPoint.Y);

            return new RectangleF(position, size);
        }

        private List<PointF> GetGlobalPoints(GameObject gameObject)
        {
            List<PointF> globalPoints = new List<PointF>();

            foreach (var component in gameObject.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        PointF globalPoint = TransformPoint(localPoint, gameObject.Transform);
                        globalPoints.Add(globalPoint);
                    }
                }
            }

            return globalPoints;
        }

        // Method to transform a local point to global point using the given transform
        private PointF TransformPoint(PointF point, TransformComponent transform)
        {
            // Rotate the point around the origin
            PointF rotatedPoint = RotatePoint(point, PointF.Empty, transform.GlobalRotation);

            // Translate the rotated point based on the global position
            PointF globalPoint = new PointF(rotatedPoint.X + transform.GlobalPosition.X, rotatedPoint.Y + transform.GlobalPosition.Y);

            return globalPoint;
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }


    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> Children { get; private set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
            Children = new List<TransformComponent>();
        }

        public void AddChild(TransformComponent child)
        {
            child.Parent = this;
            Children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            child.Parent = null;
            Children.Remove(child);
        }

        public TransformComponent Parent { get; private set; }

        public void UpdateGlobalTransform()
        {
            // Update global position and rotation
            if (Parent != null)
            {
                // Calculate global rotation
                GlobalRotation = LocalRotation + Parent.GlobalRotation;

                // Calculate global position
                PointF rotatedPosition = RotatePoint(LocalPosition, PointF.Empty, Parent.GlobalRotation);
                GlobalPosition = new PointF(rotatedPosition.X + Parent.GlobalPosition.X, rotatedPosition.Y + Parent.GlobalPosition.Y);
            }
            else
            {
                GlobalPosition = LocalPosition;
                GlobalRotation = LocalRotation;
            }

            // Update children transforms
            foreach (var child in Children)
            {
                child.UpdateGlobalTransform();
            }
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void RotateChildren(float angleInDegrees)
        {
            foreach (var child in Children)
            {
                child.LocalRotation += angleInDegrees;
            }
        }

        public void MoveInDirection(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        private void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveGlobal(float dx, float dy)
        {
            // Move globally by adding the deltas to the global position
            GlobalPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);
        }

        public void RotateGlobal(float angleInDegrees)
        {
            // Rotate globally by adding the angle to the global rotation
            GlobalRotation += angleInDegrees;
        }

        public void ScaleGlobal(float factor)
        {
            // Scale globally by multiplying the scale factor
            Scale *= factor;
        }

    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }
        public List<Component> components;

        public GameObject()
        {
            Transform = new TransformComponent();
            components = new List<Component>();
        }

        public void AddChild(GameObject child)
        {
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalTransform();
        }

        public void Draw(Graphics graphics)
        {
            // Draw each component
            foreach (var component in components)
            {
                component.Draw(graphics);
            }
        }

        public void AddComponent(Component component)
        {
            components.Add(component);
        }

        public void RemoveComponent(Component component)
        {
            components.Remove(component);
        }
    }

    public abstract class Component
    {
        public abstract void Draw(Graphics graphics);
    }

    public class MeshComponent : Component
    {
        public List<PointF> localPoints;
        private GameObject gameObject;

        public MeshComponent(List<PointF> localPoints, GameObject gameObject)
        {
            this.localPoints = localPoints;
            this.gameObject = gameObject;
        }

        public override void Draw(Graphics graphics)
        {
            // Draw the mesh
            if (localPoints.Count < 3)
                return; // Cannot draw a mesh with less than 3 points

            // Transform local points to global points
            PointF[] globalPoints = new PointF[localPoints.Count];
            for (int i = 0; i < localPoints.Count; i++)
            {
                PointF rotatedPoint = RotatePoint(localPoints[i], PointF.Empty, gameObject.Transform.GlobalRotation);
                PointF globalPoint = new PointF(rotatedPoint.X + gameObject.Transform.GlobalPosition.X,
                                                 rotatedPoint.Y + gameObject.Transform.GlobalPosition.Y);
                globalPoints[i] = globalPoint;
            }

            graphics.DrawPolygon(Pens.Black, globalPoints);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

    }
}
*/








/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{

    public class Obstacle : GameObject
    {
        // Konstruktor für die Hindernisse
        public Obstacle(PointF position, List<PointF> localPoints)
        {
            Transform.LocalPosition = position;
            MeshComponent meshComponent = new MeshComponent(localPoints, this);
            AddComponent(meshComponent);
        }
    }

    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;
        private List<Obstacle> obstacles;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            rootObject.Transform.MoveInDirection(100f);
            rootObject.Update();

            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);
            childObject.Update();

            MeshComponent rootMesh = new MeshComponent(new List<PointF>
        {
            new PointF(-25, -45),
            new PointF(-25, 25),
            new PointF(25, 25),
            new PointF(25, -75)
        }, rootObject);

            rootObject.AddComponent(rootMesh);

            MeshComponent childMesh = new MeshComponent(new List<PointF>
        {
            new PointF(-15, -15),
            new PointF(-15, 15),
            new PointF(15, 15),
            new PointF(15, -15)
        }, childObject);

            childObject.AddComponent(childMesh);

            // Initialize obstacles
            obstacles = new List<Obstacle>();

            obstacles.Add(new Obstacle(new PointF(200, 200), new List<PointF>
        {
            new PointF(-50, -50),
            new PointF(-50, 50),
            new PointF(50, 50),
            new PointF(50, -50)
        }));
            obstacles.Add(new Obstacle(new PointF(400, 300), new List<PointF>
        {
            new PointF(-40, -40),
            new PointF(-40, 40),
            new PointF(40, 40),
            new PointF(40, -40)
        }));

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw game objects
            rootObject.Draw(e.Graphics);
            childObject.Draw(e.Graphics);

            foreach (var obstacle in obstacles)
            {
                RectangleF rect1 = GetBoundingBox(obstacle);
                e.Graphics.DrawRectangle(Pens.Red, Rectangle.Round(rect1) );

                obstacle.Draw(e.Graphics);
            }

        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.Rotate(-5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.Rotate(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    rootObject.Transform.RotateChildren(5f); // Rotate children around the root
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();
            childObject.Update();

            // Check for collisions with obstacles
            foreach (var obstacle in obstacles)
            {
                obstacle.Update();

                if (CheckCollision(rootObject, obstacle))
                {
                    // Handle collision
                    Console.WriteLine("Collision with obstacle!");
                    // Implement collision handling logic here
                }
            }

            // Redraw the form
            this.Invalidate();
        }

        private bool CheckCollision(GameObject obj1, GameObject obj2)
        {
            // Implement collision detection logic here
            // For simplicity, let's assume all objects are rectangles and check if their bounding boxes intersect
            RectangleF rect1 = GetBoundingBox(obj1);
            RectangleF rect2 = GetBoundingBox(obj2);
            return rect1.IntersectsWith(rect2);
        }

        // Method to get the bounding box of a game object
        private RectangleF GetBoundingBox(GameObject obj)
        {
            // Initialize min and max points with extreme values
            PointF minPoint = new PointF(float.MaxValue, float.MaxValue);
            PointF maxPoint = new PointF(float.MinValue, float.MinValue);

            // Iterate through all mesh components of the object
            foreach (var component in obj.components)
            {
                if (component is MeshComponent meshComponent)
                {
                    // Iterate through all local points of the mesh
                    foreach (var localPoint in meshComponent.localPoints)
                    {
                        // Transform local point to global point
                        PointF globalPoint = TransformPoint(localPoint, obj.Transform);

                        // Update min and max points based on the global point
                        minPoint.X = Math.Min(minPoint.X, globalPoint.X);
                        minPoint.Y = Math.Min(minPoint.Y, globalPoint.Y);
                        maxPoint.X = Math.Max(maxPoint.X, globalPoint.X);
                        maxPoint.Y = Math.Max(maxPoint.Y, globalPoint.Y);
                    }
                }
            }

            // Calculate the size of the bounding box
            SizeF size = new SizeF(maxPoint.X - minPoint.X, maxPoint.Y - minPoint.Y);

            // Calculate the position of the bounding box (bottom-left corner)
            PointF position = new PointF(minPoint.X, minPoint.Y);

            return new RectangleF(position, size);
        }

        // Method to transform a local point to global point using the given transform
        private PointF TransformPoint(PointF point, TransformComponent transform)
        {
            // Rotate the point around the origin
            PointF rotatedPoint = RotatePoint(point, PointF.Empty, transform.GlobalRotation);

            // Translate the rotated point based on the global position
            PointF globalPoint = new PointF(rotatedPoint.X + transform.GlobalPosition.X, rotatedPoint.Y + transform.GlobalPosition.Y);

            return globalPoint;
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> Children { get; private set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
            Children = new List<TransformComponent>();
        }

        public void AddChild(TransformComponent child)
        {
            child.Parent = this;
            Children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            child.Parent = null;
            Children.Remove(child);
        }

        public TransformComponent Parent { get; private set; }

        public void UpdateGlobalTransform()
        {
            // Update global position and rotation
            if (Parent != null)
            {
                // Calculate global rotation
                GlobalRotation = LocalRotation + Parent.GlobalRotation;

                // Calculate global position
                PointF rotatedPosition = RotatePoint(LocalPosition, PointF.Empty, Parent.GlobalRotation);
                GlobalPosition = new PointF(rotatedPosition.X + Parent.GlobalPosition.X, rotatedPosition.Y + Parent.GlobalPosition.Y);
            }
            else
            {
                GlobalPosition = LocalPosition;
                GlobalRotation = LocalRotation;
            }

            // Update children transforms
            foreach (var child in Children)
            {
                child.UpdateGlobalTransform();
            }
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void RotateChildren(float angleInDegrees)
        {
            foreach (var child in Children)
            {
                child.LocalRotation += angleInDegrees;
            }
        }

        public void MoveInDirection(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        private void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveGlobal(float dx, float dy)
        {
            // Move globally by adding the deltas to the global position
            GlobalPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);
        }

        public void RotateGlobal(float angleInDegrees)
        {
            // Rotate globally by adding the angle to the global rotation
            GlobalRotation += angleInDegrees;
        }

        public void ScaleGlobal(float factor)
        {
            // Scale globally by multiplying the scale factor
            Scale *= factor;
        }

    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }
        public List<Component> components;

        public GameObject()
        {
            Transform = new TransformComponent();
            components = new List<Component>();
        }

        public void AddChild(GameObject child)
        {
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalTransform();
        }

        public void Draw(Graphics graphics)
        {
            // Draw each component
            foreach (var component in components)
            {
                component.Draw(graphics);
            }
        }

        public void AddComponent(Component component)
        {
            components.Add(component);
        }

        public void RemoveComponent(Component component)
        {
            components.Remove(component);
        }
    }

    public abstract class Component
    {
        public abstract void Draw(Graphics graphics);
    }

    public class MeshComponent : Component
    {
        public List<PointF> localPoints;
        private GameObject gameObject;

        public MeshComponent(List<PointF> localPoints, GameObject gameObject)
        {
            this.localPoints = localPoints;
            this.gameObject = gameObject;
        }

        public override void Draw(Graphics graphics)
        {
            // Draw the mesh
            if (localPoints.Count < 3)
                return; // Cannot draw a mesh with less than 3 points

            // Transform local points to global points
            PointF[] globalPoints = new PointF[localPoints.Count];
            for (int i = 0; i < localPoints.Count; i++)
            {
                PointF rotatedPoint = RotatePoint(localPoints[i], PointF.Empty, gameObject.Transform.GlobalRotation);
                PointF globalPoint = new PointF(rotatedPoint.X + gameObject.Transform.GlobalPosition.X,
                                                 rotatedPoint.Y + gameObject.Transform.GlobalPosition.Y);
                globalPoints[i] = globalPoint;
            }

            graphics.DrawPolygon(Pens.Black, globalPoints);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

    }
}
*/







/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{
    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            rootObject.Transform.MoveInDirection(100f);
            rootObject.Update();

            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);
            childObject.Update();

            MeshComponent rootMesh = new MeshComponent(new List<PointF>
            {
                new PointF(-25, -45),
                new PointF(-25, 25),
                new PointF(25, 25),
                new PointF(25, -75)
            }, rootObject);

            rootObject.AddComponent(rootMesh);

            MeshComponent childMesh = new MeshComponent(new List<PointF>
            {
                new PointF(-15, -15),
                new PointF(-15, 15),
                new PointF(15, 15),
                new PointF(15, -15)
            }, childObject);

            childObject.AddComponent(childMesh);

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw game objects
            rootObject.Draw(e.Graphics);
            childObject.Draw(e.Graphics);
        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.Rotate(-5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.Rotate(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    rootObject.Transform.RotateChildren(5f); // Rotate children around the root
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();
            childObject.Update();

            // Redraw the form
            this.Invalidate();
        }
    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> Children { get; private set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
            Children = new List<TransformComponent>();
        }

        public void AddChild(TransformComponent child)
        {
            child.Parent = this;
            Children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            child.Parent = null;
            Children.Remove(child);
        }

        public TransformComponent Parent { get; private set; }

        public void UpdateGlobalTransform()
        {
            // Update global position and rotation
            if (Parent != null)
            {
                // Calculate global rotation
                GlobalRotation = LocalRotation + Parent.GlobalRotation;

                // Calculate global position
                PointF rotatedPosition = RotatePoint(LocalPosition, PointF.Empty, Parent.GlobalRotation);
                GlobalPosition = new PointF(rotatedPosition.X + Parent.GlobalPosition.X, rotatedPosition.Y + Parent.GlobalPosition.Y);
            }
            else
            {
                GlobalPosition = LocalPosition;
                GlobalRotation = LocalRotation;
            }

            // Update children transforms
            foreach (var child in Children)
            {
                child.UpdateGlobalTransform();
            }
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void RotateChildren(float angleInDegrees)
        {
            foreach (var child in Children)
            {
                child.LocalRotation += angleInDegrees;
            }
        }

        public void MoveInDirection(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        private void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveGlobal(float dx, float dy)
        {
            // Move globally by adding the deltas to the global position
            GlobalPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);
        }

        public void RotateGlobal(float angleInDegrees)
        {
            // Rotate globally by adding the angle to the global rotation
            GlobalRotation += angleInDegrees;
        }

        public void ScaleGlobal(float factor)
        {
            // Scale globally by multiplying the scale factor
            Scale *= factor;
        }

    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }
        private List<Component> components;

        public GameObject()
        {
            Transform = new TransformComponent();
            components = new List<Component>();
        }

        public void AddChild(GameObject child)
        {
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalTransform();
        }

        public void Draw(Graphics graphics)
        {
            // Draw each component
            foreach (var component in components)
            {
                component.Draw(graphics);
            }
        }

        public void AddComponent(Component component)
        {
            components.Add(component);
        }

        public void RemoveComponent(Component component)
        {
            components.Remove(component);
        }
    }

    public abstract class Component
    {
        public abstract void Draw(Graphics graphics);
    }

    public class MeshComponent : Component
    {
        private List<PointF> localPoints;
        private GameObject gameObject;

        public MeshComponent(List<PointF> localPoints, GameObject gameObject)
        {
            this.localPoints = localPoints;
            this.gameObject = gameObject;
        }

        public override void Draw(Graphics graphics)
        {
            // Draw the mesh
            if (localPoints.Count < 3)
                return; // Cannot draw a mesh with less than 3 points

            // Transform local points to global points
            PointF[] globalPoints = new PointF[localPoints.Count];
            for (int i = 0; i < localPoints.Count; i++)
            {
                PointF rotatedPoint = RotatePoint(localPoints[i], PointF.Empty, gameObject.Transform.GlobalRotation);
                PointF globalPoint = new PointF(rotatedPoint.X + gameObject.Transform.GlobalPosition.X,
                                                 rotatedPoint.Y + gameObject.Transform.GlobalPosition.Y);
                globalPoints[i] = globalPoint;
            }

            graphics.DrawPolygon(Pens.Black, globalPoints);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

    }
}
*/



/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{
    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;
        private List<GameObject> obstacles;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            rootObject.Transform.MoveInDirection(100f);

            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);

            // Initialize obstacles
            obstacles = new List<GameObject>();
            CreateObstacles();

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void CreateObstacles()
        {
            obstacles.Add(CreateObstacle(new PointF(200, 200)));
            obstacles.Add(CreateObstacle(new PointF(300, 300)));
            obstacles.Add(CreateObstacle(new PointF(400, 400)));
            obstacles.Add(CreateObstacle(new PointF(500, 500)));
        }

        private GameObject CreateObstacle(PointF position)
        {
            GameObject obstacle = new GameObject();
            obstacle.Transform.LocalPosition = position;
            obstacle.Update();
            return obstacle;
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw root object and its children
            rootObject.Draw(e.Graphics);
            childObject.Draw(e.Graphics);

            // Draw obstacles
            foreach (var obstacle in obstacles)
            {
                obstacle.Draw(e.Graphics);
            }
        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.Rotate(-5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.Rotate(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    rootObject.Transform.RotateChildren(5f); // Rotate children around the root
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }

            // Check for collisions with obstacles
            foreach (var obstacle in obstacles)
            {
                if (CheckCollision(rootObject, obstacle))
                {
                    MessageBox.Show("Collision detected!");
                    // Perform actions upon collision
                }
            }
        }

        private bool CheckCollision(GameObject obj1, GameObject obj2)
        {
            // Simple rectangular collision detection based on bounding boxes
            RectangleF rect1 = GetBoundingBox(obj1);
            RectangleF rect2 = GetBoundingBox(obj2);

            return rect1.IntersectsWith(rect2);
        }

        private RectangleF GetBoundingBox(GameObject obj)
        {
            // Get the bounding box of the object
            PointF position = obj.Transform.GlobalPosition;
            float size = 50; // Assuming fixed size for now
            return new RectangleF(position.X - size / 2, position.Y - size / 2, size, size);
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();
            childObject.Update();

            // Redraw the form
            this.Invalidate();
        }
    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> Children { get; private set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
            Children = new List<TransformComponent>();
        }

        public void AddChild(TransformComponent child)
        {
            child.Parent = this;
            Children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            child.Parent = null;
            Children.Remove(child);
        }

        public TransformComponent Parent { get; private set; }

        public void UpdateGlobalTransform()
        {
            // Update global position and rotation
            if (Parent != null)
            {
                // Calculate global rotation
                GlobalRotation = LocalRotation + Parent.GlobalRotation;

                // Calculate global position
                PointF rotatedPosition = RotatePoint(LocalPosition, PointF.Empty, Parent.GlobalRotation);
                GlobalPosition = new PointF(rotatedPosition.X + Parent.GlobalPosition.X, rotatedPosition.Y + Parent.GlobalPosition.Y);
            }
            else
            {
                GlobalPosition = LocalPosition;
                GlobalRotation = LocalRotation;
            }

            // Update children transforms
            foreach (var child in Children)
            {
                child.UpdateGlobalTransform();
            }
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void RotateChildren(float angleInDegrees)
        {
            foreach (var child in Children)
            {
                child.LocalRotation += angleInDegrees;
            }
        }

        public void MoveInDirection(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        private void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveGlobal(float dx, float dy)
        {
            // Move globally by adding the deltas to the global position
            GlobalPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);
        }

        public void RotateGlobal(float angleInDegrees)
        {
            // Rotate globally by adding the angle to the global rotation
            GlobalRotation += angleInDegrees;
        }

        public void ScaleGlobal(float factor)
        {
            // Scale globally by multiplying the scale factor
            Scale *= factor;
        }

    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }

        public GameObject()
        {
            Transform = new TransformComponent();
        }

        public void AddChild(GameObject child)
        {
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalTransform();
        }

        public void Draw(Graphics graphics)
        {
            // Translate graphics to the global position of the game object
            graphics.TranslateTransform(Transform.GlobalPosition.X, Transform.GlobalPosition.Y);

            // Rotate the graphics
            graphics.RotateTransform(Transform.GlobalRotation);

            // Scale the graphics
            graphics.ScaleTransform(Transform.Scale, Transform.Scale);

            // Draw a simple rectangle representing the game object
            graphics.DrawRectangle(Pens.Black, -25, -25, 50, 50);

            // Reset graphics transformations
            graphics.ResetTransform();
        }
    }
}
*/




/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{
    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            rootObject.Transform.MoveInDirection(100f);
            //rootObject.Transform.MoveGlobal(200f, 200f);
            //rootObject.Update();

            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw root object and its children
            rootObject.Draw(e.Graphics);
            childObject.Draw(e.Graphics);
        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.Rotate(-5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.Rotate(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    rootObject.Transform.RotateChildren(5f); // Rotate children around the root
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();
            childObject.Update();

            // Redraw the form
            this.Invalidate();
        }
    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> Children { get; private set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
            Children = new List<TransformComponent>();
        }

        public void AddChild(TransformComponent child)
        {
            child.Parent = this;
            Children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            child.Parent = null;
            Children.Remove(child);
        }

        public TransformComponent Parent { get; private set; }

        public void UpdateGlobalTransform()
        {
            // Update global position and rotation
            if (Parent != null)
            {
                // Calculate global rotation
                GlobalRotation = LocalRotation + Parent.GlobalRotation;

                // Calculate global position
                PointF rotatedPosition = RotatePoint(LocalPosition, PointF.Empty, Parent.GlobalRotation);
                GlobalPosition = new PointF(rotatedPosition.X + Parent.GlobalPosition.X, rotatedPosition.Y + Parent.GlobalPosition.Y);
            }
            else
            {
                GlobalPosition = LocalPosition;
                GlobalRotation = LocalRotation;
            }

            // Update children transforms
            foreach (var child in Children)
            {
                child.UpdateGlobalTransform();
            }
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void RotateChildren(float angleInDegrees)
        {
            foreach (var child in Children)
            {
                child.LocalRotation += angleInDegrees;
            }
        }

        public void MoveInDirection(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        private void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveGlobal(float dx, float dy)
        {
            // Move globally by adding the deltas to the global position
            GlobalPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);
        }

        public void RotateGlobal(float angleInDegrees)
        {
            // Rotate globally by adding the angle to the global rotation
            GlobalRotation += angleInDegrees;
        }

        public void ScaleGlobal(float factor)
        {
            // Scale globally by multiplying the scale factor
            Scale *= factor;
        }

    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }

        public GameObject()
        {
            Transform = new TransformComponent();
        }

        public void AddChild(GameObject child)
        {
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalTransform();
        }

        public void Draw(Graphics graphics)
        {
            // Translate graphics to the global position of the game object
            graphics.TranslateTransform(Transform.GlobalPosition.X, Transform.GlobalPosition.Y);

            // Rotate the graphics
            graphics.RotateTransform(Transform.GlobalRotation);

            // Scale the graphics
            graphics.ScaleTransform(Transform.Scale, Transform.Scale);

            // Draw a simple rectangle representing the game object
            graphics.DrawRectangle(Pens.Black, -25, -25, 50, 50);

            // Reset graphics transformations
            graphics.ResetTransform();
        }
    }
}
*/








/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{
    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            //rootObject.Transform.MoveInDirection(100f);
            rootObject.Transform.MoveGlobal(200f, 200f);
            rootObject.Update();

            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw root object and its children
            rootObject.Draw(e.Graphics);
            childObject.Draw(e.Graphics);
        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.Rotate(-5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.Rotate(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    rootObject.Transform.RotateChildren(5f); // Rotate children around the root
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();
            childObject.Update();

            // Redraw the form
            this.Invalidate();
        }
    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> Children { get; private set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
            Children = new List<TransformComponent>();
        }

        public void AddChild(TransformComponent child)
        {
            child.Parent = this;
            Children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            child.Parent = null;
            Children.Remove(child);
        }

        public TransformComponent Parent { get; private set; }

        public void UpdateGlobalTransform()
        {
            // Update global position and rotation
            if (Parent != null)
            {
                // Calculate global rotation
                GlobalRotation = LocalRotation + Parent.GlobalRotation;

                // Calculate global position
                PointF rotatedPosition = RotatePoint(LocalPosition, PointF.Empty, Parent.GlobalRotation);
                GlobalPosition = new PointF(rotatedPosition.X + Parent.GlobalPosition.X, rotatedPosition.Y + Parent.GlobalPosition.Y);
            }
            else
            {
                GlobalPosition = LocalPosition;
                GlobalRotation = LocalRotation;
            }

            // Update children transforms
            foreach (var child in Children)
            {
                child.UpdateGlobalTransform();
            }
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void RotateChildren(float angleInDegrees)
        {
            foreach (var child in Children)
            {
                child.LocalRotation += angleInDegrees;
            }
        }

        public void MoveInDirection(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        private void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveGlobal(float dx, float dy)
        {
            // Move globally by adding the deltas to the global position
            GlobalPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);
        }

        public void RotateGlobal(float angleInDegrees)
        {
            // Rotate globally by adding the angle to the global rotation
            GlobalRotation += angleInDegrees;
        }

        public void ScaleGlobal(float factor)
        {
            // Scale globally by multiplying the scale factor
            Scale *= factor;
        }

    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }

        public GameObject()
        {
            Transform = new TransformComponent();
        }

        public void AddChild(GameObject child)
        {
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalTransform();
        }

        public void Draw(Graphics graphics)
        {
            // Translate graphics to the global position of the game object
            graphics.TranslateTransform(Transform.GlobalPosition.X, Transform.GlobalPosition.Y);

            // Rotate the graphics
            graphics.RotateTransform(Transform.GlobalRotation);

            // Scale the graphics
            graphics.ScaleTransform(Transform.Scale, Transform.Scale);

            // Draw a simple rectangle representing the game object
            graphics.DrawRectangle(Pens.Black, -25, -25, 50, 50);

            // Reset graphics transformations
            graphics.ResetTransform();
        }
    }
}
*/





/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{
    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw root object and its children
            rootObject.Draw(e.Graphics);
        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.MoveForward(5f);
                    break;
                case Keys.Down:
                    rootObject.Transform.MoveBackward(5f);
                    break;
                case Keys.Left:
                    rootObject.Transform.MoveLeft(5f);
                    break;
                case Keys.Right:
                    rootObject.Transform.MoveRight(5f);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    {
                        
                            rootObject.Transform.LocalRotation += 5f; // Rotate 5 degrees clockwise


                    }
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();

            // Redraw the form
            this.Invalidate();
        }
    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; set; }
        public float LocalRotation { get; set; }
        public float GlobalRotation { get; set; }
        public float Scale { get; set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            LocalRotation = 0f;
            GlobalRotation = 0f;
            Scale = 1f;
        }

        public void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void ScaleBy(float factor)
        {
            Scale *= factor;
        }

        public void MoveForward(float distance)
        {
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveBackward(float distance)
        {
            MoveForward(-distance);
        }

        public void MoveLeft(float distance)
        {
            float angleInRadians = (GlobalRotation - 90f) * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);
            Move(dx, dy);
        }

        public void MoveRight(float distance)
        {
            MoveLeft(-distance);
        }

        public void MoveInDirection(float distance)
        {
            MoveForward(distance);
        }

        public void UpdateGlobalTransform(PointF parentGlobalPosition, float parentGlobalRotation)
        {
            GlobalPosition = new PointF(parentGlobalPosition.X + LocalPosition.X, parentGlobalPosition.Y + LocalPosition.Y);
            GlobalRotation = parentGlobalRotation + LocalRotation;
        }
    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }
        public List<GameObject> Children { get; private set; }

        public GameObject()
        {
            Transform = new TransformComponent();
            Children = new List<GameObject>();
        }

        public void AddChild(GameObject child)
        {
            Children.Add(child);
        }

        public void RemoveChild(GameObject child)
        {
            Children.Remove(child);
        }

        public void Update()
        {
            UpdateGlobalTransformRecursive(PointF.Empty, 0f);
        }

        private void UpdateGlobalTransformRecursive(PointF parentGlobalPosition, float parentGlobalRotation)
        {
            Transform.UpdateGlobalTransform(parentGlobalPosition, parentGlobalRotation);
            foreach (var child in Children)
            {
                child.UpdateGlobalTransformRecursive(Transform.GlobalPosition, Transform.GlobalRotation);
            }
        }

        public void Draw(Graphics graphics)
        {
            DrawRecursive(graphics);
        }

        private void DrawRecursive(Graphics graphics)
        {
            graphics.TranslateTransform(Transform.GlobalPosition.X, Transform.GlobalPosition.Y);
            graphics.RotateTransform(Transform.GlobalRotation);
            graphics.ScaleTransform(Transform.Scale, Transform.Scale);
            graphics.DrawRectangle(Pens.Black, -25, -25, 50, 50);
            graphics.ResetTransform();

            foreach (var child in Children)
            {
                child.DrawRecursive(graphics);
            }
        }
    }
}
*/



/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{
    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw root object and its children
            rootObject.Draw(e.Graphics);
        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.Move(0, -5);
                    break;
                case Keys.Down:
                    rootObject.Transform.Move(0, 5);
                    break;
                case Keys.Left:
                    rootObject.Transform.Move(-5, 0);
                    break;
                case Keys.Right:
                    rootObject.Transform.Move(5, 0);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    {
                        rootObject.Transform.Rotate(5f); // Rotate 5 degrees clockwise
                        foreach(GameObject g in rootObject.children)
                        {
                            g.Transform.LocalRotation = rootObject.Transform.GlobalRotation;
                        }
                    }
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();

            // Redraw the form
            this.Invalidate();
        }
    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float LocalRotation { get; set; }
        public float GlobalRotation { get; private set; }
        public float Scale { get; set; }

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            LocalRotation = 0f;
            GlobalRotation = 0f;
            Scale = 1f;
        }

        public void Move(float dx, float dy)
        {
            LocalPosition = new PointF(LocalPosition.X + dx, LocalPosition.Y + dy);
        }

        public void Rotate(float angleInDegrees)
        {
            LocalRotation += angleInDegrees;
        }

        public void MoveInDirection(float distance)
        {
            // Berechnen Sie den Bewegungsvektor basierend auf der aktuellen Rotation
            float angleInRadians = GlobalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);

            // Bewegen Sie das Objekt entlang des Bewegungsvektors
            PointF newPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);

            // Aktualisieren Sie die Position des Objekts
            GlobalPosition = newPosition;
        }



        // Methoden für Skalierung, globale Transformationen usw. können hier hinzugefügt werden

        public void UpdateGlobalTransform(PointF parentGlobalPosition, float parentGlobalRotation)
        {
            // Berechnen Sie die globale Position und Rotation basierend auf der Elterntransformationshierarchie
            GlobalPosition = new PointF(parentGlobalPosition.X + LocalPosition.X, parentGlobalPosition.Y + LocalPosition.Y);
            GlobalRotation = parentGlobalRotation + LocalRotation;
        }
    }

    public class GameObject
    {
        public TransformComponent Transform { get; private set; }
        public List<GameObject> children;

        public GameObject()
        {
            Transform = new TransformComponent();
            children = new List<GameObject>();
        }

        public void AddChild(GameObject child)
        {
            children.Add(child);
        }

        public void RemoveChild(GameObject child)
        {
            children.Remove(child);
        }

        public void Update()
        {
            // Aktualisieren Sie die globale Transformation dieses Spielobjekts und aller seiner Kinder
            UpdateGlobalTransformRecursive(PointF.Empty, 0f);
        }

        private void UpdateGlobalTransformRecursive(PointF parentGlobalPosition, float parentGlobalRotation)
        {
            // Aktualisieren Sie zuerst die globale Transformation dieses Spielobjekts
            Transform.UpdateGlobalTransform(parentGlobalPosition, parentGlobalRotation);

            // Aktualisieren Sie dann die globale Transformation aller Kinder dieses Spielobjekts rekursiv
            foreach (var child in children)
            {
                child.UpdateGlobalTransformRecursive(Transform.GlobalPosition, Transform.GlobalRotation);
            }
        }

        public void Draw(Graphics graphics)
        {
            // Zeichnen Sie dieses Spielobjekt und alle seine Kinder
            DrawRecursive(graphics);
        }

        private void DrawRecursive(Graphics graphics)
        {

            PaintForwardVector(graphics);


            // Zeichnen Sie dieses Spielobjekt
            graphics.TranslateTransform(Transform.GlobalPosition.X, Transform.GlobalPosition.Y);
            graphics.RotateTransform(Transform.GlobalRotation);
            graphics.ScaleTransform(Transform.Scale, Transform.Scale);
            graphics.DrawRectangle(Pens.Black, -25, -25, 50, 50);
            graphics.ResetTransform();

            // Zeichnen Sie alle Kinder dieses Spielobjekts
            foreach (var child in children)
            {
                child.DrawRecursive(graphics);
            }
        }

        private void PaintForwardVector(Graphics graphics)
        {
            // Calculate the end point of the forward vector
            PointF forwardVectorEnd = new PointF(
                Transform.GlobalPosition.X + 20f * (float)Math.Cos(Transform.GlobalRotation * Math.PI / 180f),
                Transform.GlobalPosition.Y + 20f * (float)Math.Sin(Transform.GlobalRotation * Math.PI / 180f)
            );

            // Draw the forward vector as a line
            graphics.DrawLine(Pens.Red, Transform.GlobalPosition, forwardVectorEnd);
        }
    }
}
*/


// orbital
/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{

    public partial class Form1 : Form
    {
        private GameObject rootObject;
        private GameObject childObject;

        public Form1()
        {
            // Initialize form
            this.Text = "Game Form";
            this.ClientSize = new Size(800, 600);

            // Initialize game objects
            rootObject = new GameObject();
            childObject = new GameObject();
            rootObject.AddChild(childObject);
            childObject.Transform.LocalPosition = new PointF(100, 100);

            // Subscribe to paint event
            this.Paint += GameForm_Paint;

            // Subscribe to keyboard events
            this.KeyDown += GameForm_KeyDown;

            // Start game loop
            Timer timer = new Timer();
            timer.Interval = 16; // 60 FPS
            timer.Tick += Timer_Tick;
            timer.Start();
        }

        private void GameForm_Paint(object sender, PaintEventArgs e)
        {
            // Clear the screen
            e.Graphics.Clear(Color.White);

            // Draw root object
            DrawGameObject(e.Graphics, rootObject);

            // Draw child object
            DrawGameObject(e.Graphics, childObject);
        }

        private void DrawGameObject(Graphics graphics, GameObject gameObject)
        {
            // Translate graphics to the global position of the game object
            graphics.TranslateTransform(gameObject.Transform.GlobalPosition.X, gameObject.Transform.GlobalPosition.Y);

            // Rotate the graphics
            graphics.RotateTransform(gameObject.Transform.LocalRotation);

            // Scale the graphics
            graphics.ScaleTransform(gameObject.Transform.Scale, gameObject.Transform.Scale);

            // Draw a simple rectangle representing the game object
            graphics.DrawRectangle(Pens.Black, -25, -25, 50, 50);

            // Reset graphics transformations
            graphics.ResetTransform();
        }

        private void GameForm_KeyDown(object sender, KeyEventArgs e)
        {
            // Move, rotate, or scale child object with arrow keys
            switch (e.KeyCode)
            {
                case Keys.Up:
                    rootObject.Transform.LocalPosition = new PointF(rootObject.Transform.LocalPosition.X, rootObject.Transform.LocalPosition.Y - 5);
                    break;
                case Keys.Down:
                    rootObject.Transform.LocalPosition = new PointF(rootObject.Transform.LocalPosition.X, rootObject.Transform.LocalPosition.Y + 5);
                    break;
                case Keys.Left:
                    rootObject.Transform.LocalPosition = new PointF(rootObject.Transform.LocalPosition.X - 5, rootObject.Transform.LocalPosition.Y);
                    break;
                case Keys.Right:
                    rootObject.Transform.LocalPosition = new PointF(rootObject.Transform.LocalPosition.X + 5, rootObject.Transform.LocalPosition.Y);
                    break;
                case Keys.W:
                    rootObject.Transform.MoveInDirection(5f);
                    break;
                case Keys.R:
                    {
                        rootObject.Transform.LocalRotation += 5f; // Rotate 5 degrees clockwise
                        foreach(TransformComponent t in rootObject.Transform.children)
                        {
                            t.GlobalRotation += 5f;
                            t.LocalRotation = rootObject.Transform.LocalRotation;
                        }
                    }
                    break;
                case Keys.S:
                    rootObject.Transform.Scale *= 1.1f; // Scale up by 10%
                    break;
                case Keys.D:
                    rootObject.Transform.Scale /= 1.1f; // Scale down by 10%
                    break;
            }
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            // Update the game state
            rootObject.Update();

            // Redraw the form
            this.Invalidate();
        }
    }

    public class TransformComponent
    {
        public PointF LocalPosition { get; set; }
        public PointF GlobalPosition { get; private set; }
        public float GlobalRotation { get; set; }
        public float LocalRotation { get; set; }
        public float Scale { get; set; }

        public List<TransformComponent> children = new List<TransformComponent>();

        public TransformComponent()
        {
            LocalPosition = PointF.Empty;
            GlobalPosition = PointF.Empty;
            GlobalRotation = 0f;
            LocalRotation = 0f;
            Scale = 1f;
        }

        public void AddChild(TransformComponent child)
        {
            children.Add(child);
        }

        public void RemoveChild(TransformComponent child)
        {
            children.Remove(child);
        }

        public void UpdateGlobalPosition()
        {
            PointF rotatedLocalPosition = RotatePoint(LocalPosition, PointF.Empty, GlobalRotation);
            GlobalPosition = new PointF(rotatedLocalPosition.X + ParentGlobalPosition.X, rotatedLocalPosition.Y + ParentGlobalPosition.Y);
            foreach (var child in children)
            {
                child.UpdateGlobalPosition();
            }
        }

        private PointF ParentGlobalPosition
        {
            get
            {
                return Parent != null ? Parent.GlobalPosition : PointF.Empty;
            }
        }

        public TransformComponent Parent { get; set; }

        private PointF RotatePoint(PointF point, PointF origin, float angleInDegrees)
        {
            double angleInRadians = angleInDegrees * Math.PI / 180.0;
            double cosTheta = Math.Cos(angleInRadians);
            double sinTheta = Math.Sin(angleInRadians);
            float x = (float)((point.X - origin.X) * cosTheta - (point.Y - origin.Y) * sinTheta + origin.X);
            float y = (float)((point.X - origin.X) * sinTheta + (point.Y - origin.Y) * cosTheta + origin.Y);
            return new PointF(x, y);
        }

        public void MoveInDirection(float distance)
        {
            // Berechnen Sie den Bewegungsvektor basierend auf der aktuellen Rotation
            float angleInRadians = LocalRotation * (float)Math.PI / 180.0f;
            float dx = distance * (float)Math.Cos(angleInRadians);
            float dy = distance * (float)Math.Sin(angleInRadians);

            // Bewegen Sie das Objekt entlang des Bewegungsvektors
            PointF newPosition = new PointF(GlobalPosition.X + dx, GlobalPosition.Y + dy);

            // Aktualisieren Sie die Position des Objekts
            GlobalPosition = newPosition;
        }


    }


    public class GameObject
    {
        public TransformComponent Transform { get; private set; }

        public GameObject()
        {
            Transform = new TransformComponent();
        }

        public void AddChild(GameObject child)
        {
            child.Transform.Parent = Transform;
            Transform.AddChild(child.Transform);
        }

        public void RemoveChild(GameObject child)
        {
            child.Transform.Parent = null;
            Transform.RemoveChild(child.Transform);
        }

        public void Update()
        {
            Transform.UpdateGlobalPosition();
        }
    }

}
*/




/*
using System;
using System.Drawing;
using System.Windows.Forms;

namespace _2DTest
{
    public partial class Form1 : Form
    {
        private MyPolygon polygonA;
        private MyPolygon polygonB;
        private Vector velocity;
        private Vector dragOffset;
        private MyPolygon draggedPolygon;

        public Form1()
        {
            InitializeComponent();

            // Beispielverwendung
            PointF[] pointsA = { new PointF(50, 50), new PointF(50, 100), new PointF(100, 100), new PointF(100, 50) };
            PointF[] pointsB = { new PointF(150, 150), new PointF(150, 200), new PointF(200, 200), new PointF(200, 150) };

            polygonA = new MyPolygon(pointsA);
            polygonB = new MyPolygon(pointsB);

            velocity = new Vector(1, 1);
            dragOffset = Vector.Zero;
            draggedPolygon = null;

            // Ereignishandler für das Zeichnen und Mausereignisse hinzufügen
            this.Paint += Form1_Paint;
            this.MouseDown += Form1_MouseDown;
            this.MouseMove += Form1_MouseMove;
            this.MouseUp += Form1_MouseUp;
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            // Zeichne die Polygone
            DrawPolygon(e.Graphics, polygonA.Points, Pens.Blue);
            DrawPolygon(e.Graphics, polygonB.Points, Pens.Red);
        }

        private void DrawPolygon(Graphics g, PointF[] points, Pen pen)
        {
            g.DrawPolygon(pen, points);
        }

        private void Form1_MouseDown(object sender, MouseEventArgs e)
        {
            // Überprüfe, ob die Maus über einem der Polygone liegt
            if (IsPointInPolygon(new PointF(e.X, e.Y), polygonA.Points))
            {
                draggedPolygon = polygonA;
            }
            else if (IsPointInPolygon(new PointF(e.X, e.Y), polygonB.Points))
            {
                draggedPolygon = polygonB;
            }

            if (draggedPolygon != null)
            {
                // Berechne den Offset für das Verschieben
                dragOffset = new Vector(e.X, e.Y) - new Vector(draggedPolygon.Points[0].X, draggedPolygon.Points[0].Y);
            }
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            if (draggedPolygon != null)
            {
                // Verschiebe das Polygon mit der Maus
                draggedPolygon.Offset(new Vector(e.X, e.Y) - dragOffset);
                Invalidate(); // Erzwinge das Neuzeichnen des Formulars
            }
        }

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            draggedPolygon = null;
        }

        private bool IsPointInPolygon(PointF point, PointF[] polygon)
        {
            // Überprüfe, ob ein Punkt innerhalb eines Polygons liegt (Ray-Casting-Algorithmus)
            int count = polygon.Length;
            bool inside = false;

            for (int i = 0, j = count - 1; i < count; j = i++)
            {
                if (((polygon[i].Y > point.Y) != (polygon[j].Y > point.Y)) &&
                    (point.X < (polygon[j].X - polygon[i].X) * (point.Y - polygon[i].Y) / (polygon[j].Y - polygon[i].Y) + polygon[i].X))
                {
                    inside = !inside;
                }
            }

            return inside;
        }
    }

    public struct Vector
    {
        public float X;
        public float Y;

        public Vector(float x, float y)
        {
            X = x;
            Y = y;
        }

        public static Vector Zero => new Vector(0, 0);

        public static Vector operator +(Vector a, Vector b)
        {
            return new Vector(a.X + b.X, a.Y + b.Y);
        }

        public static Vector operator -(Vector a, Vector b)
        {
            return new Vector(a.X - b.X, a.Y - b.Y);
        }

        public void Offset(Vector offset)
        {
            X += offset.X;
            Y += offset.Y;
        }
    }

    public class MyPolygon
    {
        public PointF[] Points { get; private set; }

        public MyPolygon(PointF[] points)
        {
            Points = points;
        }

        public void Offset(Vector offset)
        {
            for (int i = 0; i < Points.Length; i++)
            {
                Points[i] = new PointF(Points[i].X + offset.X, Points[i].Y + offset.Y);
            }
        }
    }
}
*/




/*
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Windows.Forms;

namespace _2DTest
{
    public partial class Form1 : Form
    {
        private PlayerObject player;
        private List<GameObject> obstacles;

        private System.Windows.Forms.Timer gameTimer;

        public Form1()
        {
            InitializeComponent();
            InitializeGame();
        }

        private void InitializeGame()
        {
            player = new PlayerObject(new PointF(100, 100));
            obstacles = new List<GameObject>
            {
                new ObstacleObject(new PointF(200, 200)),
                new ObstacleObject(new PointF(300, 300)),
                // Weitere Hindernisse hinzufügen...
            };

            player.AddChildren(obstacles);

            this.Paint += Form1_Paint;

            // Timer erstellen
            gameTimer = new System.Windows.Forms.Timer();
            gameTimer.Interval = 16; // Setze die Intervallzeit in Millisekunden (ca. 60 FPS)
            gameTimer.Tick += gameTimer_Tick;
            gameTimer.Start();

            this.MouseMove += Form1_MouseMove;
            this.KeyDown += Form1_KeyDown;

        }

        private void UpdateGame()
        {
            player.Update();
            foreach (var obstacle in obstacles)
            {
                obstacle.Update();
            }
        }

        private void Form1_Paint(object sender, PaintEventArgs e)
        {
            player.Draw(e.Graphics);
            foreach (var obstacle in obstacles)
            {
                obstacle.Draw(e.Graphics);
            }
            Console.WriteLine("Painted");
        }

        private void Form1_KeyDown(object sender, KeyEventArgs e)
        {
            player.Transform.HandleKeyPress(e.KeyCode);
        }

        private void Form1_MouseMove(object sender, MouseEventArgs e)
        {
            Console.WriteLine("Mouse Moved");
            player.Transform.HandleMouseMove(e.Location);
        }

        private void gameTimer_Tick(object sender, EventArgs e)
        {
            UpdateGame();

            Invalidate();

            Console.WriteLine("Ticked");
        }
    }

    public class Geometry
    {
        public List<PointF> Points { get; private set; }
        public List<Line> Lines { get; private set; }

        public Geometry(List<PointF> points, List<Line> lines)
        {
            Points = points;
            Lines = lines;
        }

        public void Draw(Graphics g, PointF position, float rotation)
        {
            PointF[] rotatedPoints = RotatePoints(Points.ToArray(), rotation);
            PointF[] translatedPoints = TranslatePoints(rotatedPoints, position);

            for (int i = 0; i < Lines.Count; i++)
            {
                g.DrawLine(Pens.Black, translatedPoints[Lines[i].Start], translatedPoints[Lines[i].End]);
            }

            // Markiere den Vorwärtsvektor als Linie vom Mittelpunkt
            PointF center = new PointF(translatedPoints.Average(p => p.X), translatedPoints.Average(p => p.Y));
            PointF forwardVector = new PointF(
                center.X + 20 * (float)Math.Cos(rotation),
                center.Y + 20 * (float)Math.Sin(rotation)
            );

            g.DrawLine(Pens.Red, center, forwardVector);
        }

        private PointF[] RotatePoints(PointF[] points, float angle)
        {
            float centerX = points.Average(p => p.X);
            float centerY = points.Average(p => p.Y);

            for (int i = 0; i < points.Length; i++)
            {
                float x = points[i].X - centerX;
                float y = points[i].Y - centerY;

                points[i] = new PointF(
                    (float)(x * Math.Cos(angle) - y * Math.Sin(angle) + centerX),
                    (float)(x * Math.Sin(angle) + y * Math.Cos(angle) + centerY)
                );
            }

            return points;
        }

        private PointF[] TranslatePoints(PointF[] points, PointF translation)
        {
            for (int i = 0; i < points.Length; i++)
            {
                points[i] = new PointF(points[i].X + translation.X, points[i].Y + translation.Y);
            }

            return points;
        }
    }

    public class Line
    {
        public int Start { get; set; }
        public int End { get; set; }

        public Line(int start, int end)
        {
            Start = start;
            End = end;
        }
    }

    public class GameObject
    {
        public PointF Position { get; set; }
        public float Rotation { get; set; }
        public Geometry Geometry { get; private set; }
        public List<GameObject> Children { get; private set; }

        public GameObject(PointF position, Geometry geometry)
        {
            Position = position;
            Rotation = 0f;
            Geometry = geometry;
            Children = new List<GameObject>();
        }

        public virtual void Update()
        {
            foreach (var child in Children)
            {
                child.Update();
            }
        }

        public virtual void Draw(Graphics g)
        {
            Geometry.Draw(g, Position, Rotation);

            foreach (var child in Children)
            {
                child.Draw(g);
            }
        }

        public void AddChildren(List<GameObject> children)
        {
            Children.AddRange(children);
        }
    }

    public class PlayerObject : GameObject
    {
        public float Speed { get; set; } = 5f;
        public Transform Transform { get; set; }

        public PlayerObject(PointF position) : base(position, CreatePlayerGeometry())
        {
            Transform = new Transform(this);
        }

        private static Geometry CreatePlayerGeometry()
        {
            // Hier kannst du die Punkte und Linien für die Geometrie des Spielerobjekts definieren
            List<PointF> points = new List<PointF>
            {
                new PointF(-15, -15),
                new PointF(15, -15),
                new PointF(0, 20)
            };

            List<Line> lines = new List<Line>
            {
                new Line(0, 1),
                new Line(1, 2),
                new Line(2, 0)
            };

            return new Geometry(points, lines);
        }

        public override void Update()
        {
            base.Update();
            Transform.Update();
            // Hier können spezifische Logiken für die Aktualisierung des PlayerObjects implementiert werden
        }
    }

    public class ObstacleObject : GameObject
    {
        public Transform Transform { get; set; }

        public ObstacleObject(PointF position) : base(position, CreateObstacleGeometry())
        {
            Transform = new Transform(this);
        }

        private static Geometry CreateObstacleGeometry()
        {
            // Hier kannst du die Punkte und Linien für die Geometrie des Hindernisobjekts definieren
            List<PointF> points = new List<PointF>
            {
                new PointF(-20, -20),
                new PointF(20, -20),
                new PointF(20, 20),
                new PointF(-20, 20)
            };

            List<Line> lines = new List<Line>
            {
                new Line(0, 1),
                new Line(1, 2),
                new Line(2, 3),
                new Line(3, 0)
            };

            return new Geometry(points, lines);
        }
    }

    public class Transform
    {
        private GameObject gameObject;

        public Transform(GameObject obj)
        {
            gameObject = obj;
        }

        public void Update()
        {
            // Hier können spezifische Logiken für die Aktualisierung des Transforms implementiert werden
        }

        public void HandleKeyPress(Keys key)
        {
            float moveDistance = 5f;

            switch (key)
            {
                case Keys.W:
                    Move(new PointF(moveDistance, 0));
                    break;
                case Keys.S:
                    Move(new PointF(-moveDistance, 0));
                    break;
                case Keys.A:
                    Move(new PointF(0, -moveDistance));
                    break;
                case Keys.D:
                    Move(new PointF(0, moveDistance));
                    break;
            }

            Console.WriteLine("Keypress handled");
        }

        public void HandleMouseMove(PointF mousePosition)
        {
            RotateTowards(mousePosition);
        }

        private void Move(PointF translation)
        {
            float angleInRadians = gameObject.Rotation;
            float cos = (float)Math.Cos(angleInRadians);
            float sin = (float)Math.Sin(angleInRadians);

            float dx = translation.X * cos - translation.Y * sin;
            float dy = translation.X * sin + translation.Y * cos;

            gameObject.Position = new PointF(gameObject.Position.X + dx, gameObject.Position.Y + dy);
        }

        private void RotateTowards(PointF targetPosition)
        {
            float angle = (float)Math.Atan2(targetPosition.Y - gameObject.Position.Y, targetPosition.X - gameObject.Position.X);
            gameObject.Rotation = angle;
        }


    }


}
*/