private Line FindBoundingBoxLine(CompoundBody body, Func <Vector3, double> coordinateSelector)
        {
            var min = body.Parts.Min(p => coordinateSelector(GetMinPoint(p.TryAcceptVisitor <RectangularCuboid>(this))));
            var max = body.Parts.Max(p => coordinateSelector(GetMaxPoint(p.TryAcceptVisitor <RectangularCuboid>(this))));

            return(new Line(min, max));
        }
        public object VisitCompound(CompoundBody visited)
        {
            var x = FindBoundingBoxLine(visited, pos => pos.X);
            var y = FindBoundingBoxLine(visited, pos => pos.Y);
            var z = FindBoundingBoxLine(visited, pos => pos.Z);

            return(new RectangularCuboid(new Vector3(x.Center, y.Center, z.Center), x.Length, y.Length, z.Length));
        }
        public Body Visit(CompoundBody element)
        {
            var newParts = element.Parts
                           .Select(part => part.Accept(this))
                           .ToList();

            return(new CompoundBody(newParts));
        }
        public void CompoundBody_Of_TwoCuboids_BoundingBox_Correct(double x0, double y0, double z0, double x1, double y1, double z1, double expectedSizeX, double expectedSizeY, double expectedSizeZ)
        {
            var compoundBody = new CompoundBody(new[]
            {
                new RectangularCuboid(new Vector3(x0, y0, z0), 4, 4, 4),
                new RectangularCuboid(new Vector3(x1, y1, z1), 4, 4, 4),
            });
            var boundingBox = compoundBody.TryAcceptVisitor <RectangularCuboid>(new BoundingBoxVisitor());

            Assert.AreEqual(expectedSizeX, boundingBox.SizeX, "SizeX");
            Assert.AreEqual(expectedSizeY, boundingBox.SizeY, "SizeY");
            Assert.AreEqual(expectedSizeZ, boundingBox.SizeZ, "SizeZ");
        }
        public object VisitCompound(CompoundBody visited)
        {
            var parts = visited.Parts.Select(p =>
            {
                if (p is CompoundBody cb)
                {
                    return((Body)(CompoundBody)VisitCompound(cb));
                }
                return((RectangularCuboid)p.Accept(this));
            })
                        .ToList();

            return(new CompoundBody(parts));
        }
        public Body Visit(CompoundBody element)
        {
            var boundingBoxes = element.Parts.Select(part => (RectangularCuboid)part.Accept(this));

            var(minPosX, maxPosX) = boundingBoxes.GetRectangularListMaxAndMin(
                x => x.SizeX, x => x.Position.X);
            var(minPosY, maxPosY) = boundingBoxes.GetRectangularListMaxAndMin(
                x => x.SizeY, x => x.Position.Y);
            var(minPosZ, maxPosZ) = boundingBoxes.GetRectangularListMaxAndMin(
                x => x.SizeZ, x => x.Position.Z);

            var position = new Vector3((minPosX + maxPosX) / 2, (minPosY + maxPosY) / 2, (minPosZ + maxPosZ) / 2);

            return(new RectangularCuboid(position, maxPosX - minPosX, maxPosY - minPosY, maxPosZ - minPosZ));
        }
 private void AssertCompoundBodyBoxified(CompoundBody source, CompoundBody boxifiedBody)
 {
     Assert.AreEqual(source.Parts.Count, boxifiedBody.Parts.Count);
     for (var i = 0; i < source.Parts.Count; i++)
     {
         if (source.Parts[i] is CompoundBody compound)
         {
             Assert.That(boxifiedBody.Parts[i], Is.InstanceOf <CompoundBody>());
             AssertCompoundBodyBoxified(compound, (CompoundBody)boxifiedBody.Parts[i]);
         }
         else
         {
             Assert.That(boxifiedBody.Parts[i], Is.InstanceOf <RectangularCuboid>());
             Assert.IsTrue(source.Parts[i].Position.Equals(boxifiedBody.Parts[i].Position, Constants.Inaccuracy),
                           $"{boxifiedBody.Parts[i].Position} != {source.Parts[i].Position}");
         }
     }
 }
        public void CompoundBody_BoxifyVisitor_IsCorrect()
        {
            var ball      = new Ball(new Vector3(1, 2, 3), 4);
            var box       = new RectangularCuboid(new Vector3(8, 9, 10), 2, 3, 4);
            var cylinder  = new Cylinder(new Vector3(-5, -6, -10), 3, 5);
            var cBall     = new Ball(new Vector3(12, 12, 12), 2);
            var cBox      = new RectangularCuboid(new Vector3(-12, -12, -12), 2, 2, 2);
            var cCylinder = new Cylinder(new Vector3(25, 25, 25), 2, 3);
            var compound  = new CompoundBody(new List <Body> {
                cBall, cBox, cCylinder
            });
            var compoundBody = new CompoundBody(new List <Body> {
                ball, box, cylinder, compound
            });

            var actual = compoundBody.TryAcceptVisitor <CompoundBody>(new BoxifyVisitor());

            AssertCompoundBodyBoxified(compoundBody, actual);
        }
        public Body VisitCompoundBody(CompoundBody compoundBody)
        {
            var minVectors = new List <Vector3>();
            var maxVectors = new List <Vector3>();

            SetMinAndMaxVectors(compoundBody.Parts, minVectors, maxVectors);

            var mostMinPoint = GetMinVector(minVectors);
            var mostMaxPoint = GetMaxlVector(maxVectors);

            var sizeX = mostMaxPoint.X - mostMinPoint.X;
            var sizeY = mostMaxPoint.Y - mostMinPoint.Y;
            var sizeZ = mostMaxPoint.Z - mostMinPoint.Z;

            var position = new Vector3(mostMinPoint.X + sizeX / 2,
                                       mostMinPoint.Y + sizeY / 2, mostMinPoint.Z + sizeZ / 2);

            return(new RectangularCuboid(position, sizeX, sizeY, sizeZ));
        }