예제 #1
0
        public void Paint(PaintEventArgs e)
        {
            for (int i = 0; i < Spheres.Count - 1; i++)
            {
                for (int j = i + 1; j < Spheres.Count; j++)
                {
                    Sphere3d s1 = Spheres[i];
                    Sphere3d s2 = Spheres[j];
                    float?   t  = CollisionSystem.CalculateCollision(s1, s2);

                    if (t.HasValue && t.Value != 0)
                    {
                        s1.Move(t.Value, ref c1);
                        //collp.X = s1.Direction.X * t.Value + s1.Position.X;
                        //collp.Y = s1.Direction.Y * t.Value + s1.Position.Y;
                        e.Graphics.DrawCircle(Pens.Red, c1.Position.X, c1.Position.Y, s1.Radius);
                        s2.Move(t.Value, ref c2);
                        //collp.X = s2.Direction.X * t.Value + s2.Position.X;
                        //collp.Y = s2.Direction.Y * t.Value + s2.Position.Y;
                        e.Graphics.DrawCircle(Pens.Red, c2.Position.X, c2.Position.Y, s2.Radius);
                        e.Graphics.DrawLine(CollisionCirecleCentersPen, c1.Position.X, c1.Position.Y, c2.Position.X, c2.Position.Y);
                        CollisionSystem.CalculateReaction(0, c1, c2);
                        float tx = c1.Position.X + c1.Direction.X;
                        float ty = c1.Position.Y + c1.Direction.Y;
                        e.Graphics.DrawLine(Pens.Black, c1.Position.X, c1.Position.Y, tx, ty);
                    }
                }
            }
        }
예제 #2
0
파일: Sphere3d.cs 프로젝트: fdafadf/main
 public virtual void Move(float t, ref Sphere3d s)
 {
     s.Position.X  = Position.X + Direction.X * t;
     s.Position.Y  = Position.Y + Direction.Y * t;
     s.Position.Z  = Position.Z + Direction.Z * t;
     s.Direction.X = Direction.X;
     s.Direction.Y = Direction.Y;
     s.Direction.Z = Direction.Z;
 }
예제 #3
0
        private static void WriteDebugInfo(float rotationY, Sphere3d s1, Sphere3d s2)
        {
            string vector(Vector3d v)
            {
                return($"new Vector3d({v.X}f, {v.Y}f, {v.Z}f)");
            }

            Console.WriteLine($"float rotationY = {rotationY}f;");
            Console.WriteLine($"Sphere3d s1 = new Sphere3d({vector(s1.Position)}, {s1.Radius}, {vector(s1.Direction)});");
            Console.WriteLine($"Sphere3d s2 = new Sphere3d({vector(s2.Position)}, {s1.Radius}, {vector(s2.Direction)});");
        }
예제 #4
0
        public void Paint(PaintEventArgs e, Pen pen, Sphere3d sphere)
        {
            float doubleRadius = sphere.Radius * 2;
            float sx           = (sphere.Position.X + TranslateX) * Scale;
            float sz           = (sphere.Position.Z + TranslateZ) * Scale;

            e.Graphics.DrawCircle(pen, sx, sz, sphere.Radius * Scale);
            e.Graphics.DrawArrow(pen, sx, sz, sx + sphere.Direction.X * Scale, sz + sphere.Direction.Z * Scale);

            if (Reaction != null)
            {
                e.Graphics.DrawArrow(Pens.Red, sx, sz, sx + Reaction.X * Scale, sz + Reaction.Z * Scale);
            }
        }
예제 #5
0
        public PathfinderScene(int sphereCount, int width, int height, Random random)
        {
            Obstacles = new List <Sphere3d>();

            for (int i = 0; i < sphereCount; i++)
            {
                Obstacles.Add(RandomSphere(random, width, height, dynamic: false));
            }

            Checkpoint = RandomNonCollidingSphere(random, width, height, Obstacles, dynamic: false);
            Vehicle    = new Sphere3dVehicle(RandomNonCollidingSphere(random, width, height, Obstacles, dynamic: true));
            List <Sphere3d> allSpheres = new List <Sphere3d>();

            allSpheres.AddRange(Obstacles);
            allSpheres.Add(Checkpoint);
            allSpheres.Add(Vehicle.Sphere);
            CollisionSystem = new CollisionSystem(allSpheres, new Triangle[] { });
        }
예제 #6
0
        public Race(int numberOfSpheres)
        {
            Spheres      = new List <Sphere3d>();
            PlayerSphere = new Sphere3d(new Vector3d(), 0.2f, new Vector3d());
            Speed        = 0.1f;
            RotationY    = 45;
            Input        = new RaceInputModel();
            Random random = new Random();

            Spheres.Add(PlayerSphere);

            for (int i = 0; i < numberOfSpheres; i++)
            {
                float x = random.Next(100);
                float z = random.Next(100) - 50;
                float r = (float)random.NextDouble() * 2.0f + 0.2f;
                Spheres.Add(new Sphere3d(new Vector3d(x, 0, z), r, new Vector3d()));
            }

            Ground          = new Triangle(new Vector3d(-100, -5, -50), new Vector3d(0, -5, 50), new Vector3d(100, -5, -50));
            collisionSystem = new CollisionSystem(Spheres, new Triangle[] { Ground });
        }
예제 #7
0
 public static float?CalculateCollision(Sphere3d s1, Sphere3d s2)
 {
     return(null);
     //Vector3d.Sub(s1.Position, s2.Position, ref vecs);
     //Vector3d.Sub(s1.Direction, s2.Direction, ref vecv);
     //float radiusSum = s1.Radius + s2.Radius;
     //float c = vecs.Dot(vecs) - radiusSum * radiusSum;
     //float t = 0;
     //
     //if (c < 0)
     //{
     //    return 0;
     //}
     //else
     //{
     //    float a = vecv.Dot(vecv);
     //    float b = vecv.Dot(vecs);
     //
     //    if (b >= 0)
     //    {
     //        return null;
     //    }
     //    else
     //    {
     //        float d = b * b - a * c;
     //
     //        if (d < 0)
     //        {
     //            return null;
     //        }
     //        else
     //        {
     //            t = (float)(-b - Math.Sqrt(d)) / a;
     //            return t;
     //        }
     //    }
     //}
 }
예제 #8
0
        public static float?CalculateCollision(Sphere3d s1, Sphere3d s2)
        {
            Vector3d.Sub(s1.Position, s2.Position, ref vecs);
            Vector3d.Sub(s1.Direction, s2.Direction, ref vecv);
            float radiusSum = s1.Radius + s2.Radius;
            float c         = vecs.Dot(vecs) - radiusSum * radiusSum;
            float t         = 0;

            if (c < 0)
            {
                return(0);
            }
            else
            {
                float a = vecv.Dot(vecv);
                float b = vecv.Dot(vecs);

                if (b >= 0)
                {
                    return(null);
                }
                else
                {
                    float d = b * b - a * c;

                    if (d < 0)
                    {
                        return(null);
                    }
                    else
                    {
                        t = (float)(-b - Math.Sqrt(d)) / a;
                        return(t);
                    }
                }
            }
        }
예제 #9
0
파일: Sphere3d.cs 프로젝트: fdafadf/main
        public bool IsColliding(Sphere3d s)
        {
            double d = Position.Distance(s.Position);

            return(d < Radius + s.Radius);
        }
예제 #10
0
파일: Sphere3d.cs 프로젝트: fdafadf/main
 public void Set(Sphere3d s)
 {
     Position.Set(s.Position);
     Direction.Set(s.Direction);
     Radius = s.Radius;
 }
예제 #11
0
 public PaintableSphere3d(Sphere3d sphere, Brush brush)
 {
     Sphere = sphere;
     Brush  = brush;
 }
예제 #12
0
 public PaintableSphere3d(Sphere3d sphere, Pen pen)
 {
     Sphere = sphere;
     Pen    = pen;
 }
예제 #13
0
 public Sphere3dVehicle(Sphere3d sphere)
 {
     Sphere = sphere;
 }
예제 #14
0
        public float?Update(float rotationY, float t)
        {
            float?        result        = null;
            HashSet <int> toRecalculate = new HashSet <int>();

            if (t >= closestTime)
            {
                Console.WriteLine("Collision");
                MoveObjects(closestTime);
                Sphere3d s1 = Objects[closest.X];
                Sphere3d s2 = Objects[closest.Y];
                result = CalculateReaction(rotationY, s1, s2);
                SubstractCollisionTimes(closestTime);
                toRecalculate.Add(closest.X);
                toRecalculate.Add(closest.Y);
            }
            else
            {
                MoveObjects(t);
                SubstractCollisionTimes(t);
                closestTime -= t;
            }

            for (int i = 0; i < Objects.Count; i++)
            {
                Sphere3d sphere = Objects[i];

                if (sphere.Position.X < 0 && sphere.Direction.X < 0)
                {
                    sphere.Direction.X = -sphere.Direction.X;
                    toRecalculate.Add(i);
                }

                if (sphere.Position.X > 800 && sphere.Direction.X > 0)
                {
                    sphere.Direction.X = -sphere.Direction.X;
                    toRecalculate.Add(i);
                }

                if (sphere.Position.Y < 0 && sphere.Direction.Y < 0)
                {
                    sphere.Direction.Y = -sphere.Direction.Y;
                    toRecalculate.Add(i);
                }

                if (sphere.Position.Y > 600 && sphere.Direction.Y > 0)
                {
                    sphere.Direction.Y = -sphere.Direction.Y;
                    toRecalculate.Add(i);
                }
            }

            foreach (int i in toRecalculate)
            {
                RecalculateCollisions(i);
            }

            if (toRecalculate.Count > 0)
            {
                RecalculateClosestCollision();
            }

            return(result);
        }
예제 #15
0
        public static float?CalculateReaction(float rotationY, Sphere3d s1, Sphere3d s2)
        {
            float?   result = null;
            Vector3d n      = s1.Position - s2.Position;

            n.Normalize();
            n.Mul(n.Dot(s1.Direction) * 2);
            Vector3d r = s1.Direction - n;

            if (s2 != null)
            {
                //Vector3d direction = new Vector3d();
                //direction.Set(s1.Direction);
                //direction.Normalize();
                result = 57.29577f * (float)Math.Atan2(r.Z, r.X);

                CollisionForm.RotationY    = rotationY;
                CollisionForm.NewRotationY = result.Value;
                CollisionForm.Sphere1      = s1;
                CollisionForm.Sphere2      = s2;
                CollisionForm.Reaction     = r;
                CollisionForm.Empty        = false;
                CollisionForm.Refresh();
            }

            s1.Direction = r;
            return(result);

            // https://math.stackexchange.com/questions/13261/how-to-get-a-reflection-vector
            //s1.Direction = r;
            //float rx =
            //float x = s1.Direction.X;
            //float y = s1.Direction.Y;
            //s1.Direction.X = 0;
            //s1.Direction.Y = 0;
            //s2.Direction.X = x;
            //s2.Direction.Y = y;
            ////s2.RotationY = s1.RotationY;
            ////s2.RecalculateDirection(5);
            //s2.RotationY = s1.RotationY;
            ////s1.RotationY += 180;

            //Vector3d vecx = new Vector3d();
            //Vector3d.Sub(s1.Position, s2.Position, ref vecx);
            //Vector3d.Normalize(vecx, ref vecx);
            //Vector3d vecv1 = new Vector3d(s1.Direction);
            //float x1 = vecx.Dot(s1.Direction);
            //Vector3d vecv1x = new Vector3d(vecx);
            //vecv1x.Mul(x1);
            //Vector3d vecv1y = new Vector3d();
            //Vector3d.Sub(vecv1, vecv1x, ref vecv1y);
            //float m1 = 1;
            //
            //vecx.Mul(-1);
            //Vector3d vecv2 = new Vector3d(s2.Direction);
            //float x2 = vecx.Dot(s2.Direction);
            //Vector3d vecv2x = new Vector3d(vecx);
            //vecv2x.Mul(x2);
            //Vector3d vecv2y = new Vector3d();
            //Vector3d.Sub(vecv2, vecv2x, ref vecv2y);
            //float m2 = 1;
            //
            //Vector3d vecv2xa = new Vector3d(vecv2x);
            //vecv2xa.Mul((2 * m2) / (m1 + m2));
            //vecv1x.Mul((m1 - m2) / (m1 - m2));
            //Vector3d.Sum(ref s1.Direction, vecv1x, vecv2xa, vecv1);
        }