예제 #1
0
        private static Sphere CreateSphereBarrier(IEnumerable <ITrackBoundary> trackObjects, [NotNull] Sphere sphere)
        {
            if (sphere == null)
            {
                throw new ArgumentNullException(nameof(sphere));
            }

            var walls = trackObjects.OfType <Wall>().GroupBy(x =>
                                                             x.Corners.Select(y => Vector3D.AbsoluteValue(y - sphere.Center)).Min())
                        .OrderBy(x => x.Key).SelectMany(x => x).Take(3).ToList();
            var corner = walls.Select(x => x.Corners).Aggregate((x, y) => x.Intersect(y).ToList()).Single();

            var intersectionPoints = walls.Select(sphere.GetInterSection).ToList();
            var barrier            = new Plane(intersectionPoints[0], intersectionPoints[1], intersectionPoints[2]);
            var sign    = barrier.DeterminePointPosition(corner);
            var checker = new PointChecker(barrier, sign);

            sphere.Checker = checker;
            return(sphere);
        }
예제 #2
0
        private static Cylinder CalculateCylinder(Line first, Line second, Line wallLine, double radius)
        {
            var angle               = Vector3D.Angle(first.Direction, second.Direction);
            var distance            = Math.Sin(90.0.ToRadian()) / Math.Sin(angle / 2) * radius;
            var minimumWallDistance = Math.Sqrt(Math.Pow(distance, 2) - Math.Pow(radius, 2));

            var referencePoint = wallLine.Contains(first.BasePoint) ? first.BasePoint : first.SecondPoint;
            var firstSign      = first.BasePoint == referencePoint ? +1 : -1;
            var secondSign     = second.BasePoint == referencePoint ? +1 : -1;

            var firstPoint  = first.GetPointOnLine(referencePoint, firstSign * minimumWallDistance);
            var secondPoint = second.GetPointOnLine(referencePoint, secondSign * minimumWallDistance);

            var crossLine  = new Line(firstPoint, secondPoint);
            var directLine = new Line(referencePoint, crossLine.ClosestPoint(referencePoint));
            var top        = directLine.GetPointOnLine(distance);

            var difference = top - referencePoint;
            var otherPoint = referencePoint == wallLine.BasePoint ? wallLine.SecondPoint : wallLine.BasePoint;
            var bottom     = otherPoint + difference;

            var basLine     = new Line(top, bottom);
            var reverseBase = new Line(bottom, top);

            var correctTop    = basLine.GetPointOnLine(radius);
            var correctBottom = reverseBase.GetPointOnLine(radius);

            var wallHeight  = Vector3D.AbsoluteValue(wallLine.SecondPoint - wallLine.BasePoint);
            var sign        = otherPoint == wallLine.BasePoint ? -1 : +1;
            var bottomPoint = firstPoint + sign * wallHeight * (wallLine.SecondPoint - wallLine.BasePoint).Normalize();

            var barrier = new Plane(firstPoint, secondPoint, bottomPoint);
            var checker = new PointChecker(barrier, barrier.DeterminePointPosition(referencePoint));

            return(new Cylinder(correctTop, correctBottom, checker, radius));
        }