public static double IntersectCylinder(Cylinder cylinder, Ray ray)
 {
     //Переменные для возврата корней квадратного уравнения
     double root1, root2;
     var a = ray.Direction.X * ray.Direction.X + ray.Direction.Y * ray.Direction.Y;
     var center = cylinder.GetAbsoluteLocation().ToPoint3D();
     var top = cylinder.GetAbsoluteLocation().ToPoint3D() + new Point3D(0, 0, cylinder.Height);
     //Вспомогательный вектор
     var vec = ray.Origin - center;
     var b = 2 * (ray.Direction.X * vec.X + ray.Direction.Y * vec.Y);
     var c = Math.Pow(ray.Origin.X - center.X, 2) +
             Math.Pow(ray.Origin.Y - center.Y, 2) -
             Math.Pow(cylinder.RBottom, 2);
     //Обработка решения
     if ((QuadEquation.Solution(a, b, c, out root1, out root2)) && ((root1 >= 0) | (root2 >= 0)))
         if (root1 >= 0)
         {
             Point3D point = ray.CalculatePoint(root1); //если координата z лежит на цилиндре, то это нам подходит
             if ((point.Z >= center.Z) && (point.Z <= center.Z + cylinder.Height))
             {
                 return ray.DistanceTo(root1);
             }
             //если координата z за пределами, то проверяем пересечения с верхней и нижней гранью
             else if (IntersectCircle(center, cylinder.RBottom, ray) != null)
             {
                 return ray.Origin.Hypot(IntersectCircle(center, cylinder.RBottom, ray).Value);
             }
             else if (IntersectCircle(top, cylinder.RBottom, ray) != null)
             {
                 return ray.Origin.Hypot(IntersectCircle(top, cylinder.RBottom, ray).Value);
             }
             else return double.PositiveInfinity;
         }
         else //все то же самое для другого корня
         {
             Point3D point = ray.CalculatePoint(root2);
             if ((point.Z >= center.Z) && (point.Z <= center.Z + cylinder.Height))
             {
                 return ray.DistanceTo(root2);
             }
             else if (IntersectCircle(center, cylinder.RBottom, ray) != null)
             {
                 return ray.Origin.Hypot(IntersectCircle(center, cylinder.RBottom, ray).Value);
             }
             else if (IntersectCircle(top, cylinder.RBottom, ray) != null)
             {
                 return ray.Origin.Hypot(IntersectCircle(top, cylinder.RBottom, ray).Value);
             }
             else return double.PositiveInfinity;
         }
     else
     {
         return double.PositiveInfinity;
     }
 }
Beispiel #2
0
		public static DirectXModel CreateCyllinder(Device device, Cylinder cyl)
		{
			var drmodel = new DirectXModel
			              	{
			              		Mesh = DirectXPrimitives.CreateCylinderMesh(device, cyl.RBottom, cyl.RTop, cyl.Height),
			              		ModifierMatrix = Matrix.Translation(0, 0, (float)(cyl.Height / 2))
			              	};

			var brushes = new[]
			              	{
			              		cyl.Top, cyl.Bottom, cyl.Side
			              	};

			drmodel.Mesh.SetMaterials(GetMaterialsFromBrushes(device, cyl.DefaultColor, drmodel, brushes));
			return drmodel;
		}
Beispiel #3
0
		public void Visit(Cylinder visitable)
		{
			IPhysical physical = PhysicalManager.MakeCyllinder(visitable.RBottom, visitable.RTop, visitable.Height);
            physical.Body = visitable;
            AfterCreating(visitable, physical);
		}
 public void RayTest(Ray ray, Cylinder cylinder, double distance)
 {
     var computedDistance = Intersector.IntersectCylinder(cylinder, ray);
     Assert.AreEqual(distance, computedDistance);
    // Console.WriteLine("Expected: {0}. But was: {1}", distance, computedDistance);
 }
Beispiel #5
0
        public Body CreateWorld(ICvarcEngine engine, ISceneSettings _settings)
        {
            Settings = (SceneSettings)_settings;
            var root = new Body();

            var first = new Cylinder
            {
                Height = 20,
                RTop = 10,
                RBottom = 10,
                Location = new Frame3D(-150 + 25 - 10, 100 - 25 + 10, 3),
                DefaultColor = Color.DarkViolet,
                IsMaterial = true,
                Density = Density.Iron,
                FrictionCoefficient = 0,
                Top = new PlaneImageBrush { Image = new Bitmap(GetResourceStream("red.png")) },
                Type = "Robot"
            };
            var second = new Cylinder
            {
                Height = 20,
                RTop = 10,
                RBottom = 10,
                Location = new Frame3D(150 - 25 + 10, 100 - 25 + 10, 3, Angle.Zero, Angle.Pi, Angle.Zero),
                DefaultColor = Color.DarkViolet,
                IsMaterial = true,
                Density = Density.Iron,
                FrictionCoefficient = 0,
                Top = new PlaneImageBrush { Image = new Bitmap(GetResourceStream("blue.png")) },
                Type = "Robot"
            };
            root.Add(first);
            root.Add(second);

            first.Collision += body => engine.RaiseOnCollision(first.Id.ToString(), body.Id.ToString(), CollisionType.RobotCollision);
            second.Collision += body => engine.RaiseOnCollision(second.Id.ToString(), body.Id.ToString(), CollisionType.RobotCollision);
            
            root.Add(new Box
            {
                XSize = 300,
                YSize = 200,
                ZSize = 3,
                DefaultColor = Color.White,
                Top = new SolidColorBrush { Color = Color.Yellow },
                IsStatic = true,
                Type = "floor",
            });

            foreach (var detail in Settings.Details)
            {
                Color color = Color.White;
                string name = "D";
                switch (detail.Color)
                {
                    case DetailColor.Red: color = Color.Red; name += "R"; break;
                    case DetailColor.Blue: color = Color.Blue; name += "B"; break;
                    case DetailColor.Green: color = Color.Green; name += "G"; break;
                }

                var box = new Box
                {
                    XSize = 15,
                    YSize = 15,
                    ZSize = 15,
                    Location = new Frame3D(-150 + 25 + detail.Location.X * 50, 100 - 25 - 50 * detail.Location.Y, 0),
                    DefaultColor = color,
                    Type = name,
                    IsMaterial = true,
                    IsStatic = false,
                    FrictionCoefficient = 8
                };
                root.Add(box);

                box.Collision += body =>
                    {
                        if (box.Parent.Id == first.Id && body.Id == second.Id)
                            engine.RaiseOnCollision(second.Id.ToString(), first.Id.ToString(), CollisionType.RobotCollision);
                        if (box.Parent.Id == second.Id && body.Id == first.Id)
                            engine.RaiseOnCollision(first.Id.ToString(), second.Id.ToString(), CollisionType.RobotCollision);
                    };
            }

            CreateWalls(root, Settings.HorizontalWalls, 50, 10, 15, "HW", (x, y) => new Point(-150 + 25 + x * 50, 100 - (y + 1) * 50));
            CreateWalls(root, Settings.VerticalWalls, 10, 50, 14, "VW", (x, y) => new Point(-150 + (x + 1) * 50, 100 - 25 - y * 50));


            CreateBorders(root);

            return root;
        }
Beispiel #6
0
			public void TexturedCylinder (Cylinder cylinder, int textureCount)
			{
				Assert.True(_modelFactory.TryGetResult(cylinder, out _model));
				Assert.AreEqual(textureCount, _model.Textures.Count);
				Assert.AreEqual(3, _model.Mesh.GetMaterials().Length);
			}