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; } }
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; }
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); }
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; }
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); }