Ejemplo n.º 1
0
        /// <summary>
        ///     The volume of the bounding box.
        ///     Note that antipodal points would result in an infinite number of great circles, but can
        ///     be ignored since we are assuming the thickness of this solid is greater than 0.
        /// </summary>
        /// <param name="gaussianSphere">The gaussian sphere.</param>
        /// <param name="vector1">The vector1.</param>
        /// <param name="vector2">The vector2.</param>
        /// <param name="referenceArc">The reference arc.</param>
        internal GreatCircleOrthogonalToArc(GaussianSphere gaussianSphere, double[] vector1, double[] vector2,
                                            Arc referenceArc)
        {
            ArcList       = new List <Arc>();
            Intersections = new List <Intersection>();
            var tempIntersections = new List <Intersection>();

            ReferenceVertices = new List <Vertex>();
            Normal            = vector1.crossProduct(vector2);
            foreach (var arc in gaussianSphere.Arcs)
            {
                var segmentBool = false;
                //Create two planes given arc and the great circle
                var norm2 = arc.Nodes[0].Vector.crossProduct(arc.Nodes[1].Vector);
                //Check whether the planes are the same.
                if (Math.Abs(Normal[0] - norm2[0]) < 0.0001 && Math.Abs(Normal[1] - norm2[1]) < 0.0001 &&
                    Math.Abs(Normal[2] - norm2[2]) < 0.0001)
                {
                    segmentBool = true; //All points intersect
                }
                if (Math.Abs(Normal[0] + norm2[0]) < 0.0001 && Math.Abs(Normal[1] + norm2[1]) < 0.0001 &&
                    Math.Abs(Normal[2] + norm2[2]) < 0.0001)
                {
                    segmentBool = true; //All points intersect
                }
                //if (Normal[0].IsPracticallySame(norm2[0]) && Normal[1].IsPracticallySame(norm2[1]) &&
                //    Normal[2].IsPracticallySame(norm2[2])) segmentBool = true; //All points intersect
                //Check whether the planes are the same, but built with opposite normals.
                //if (Normal[0].IsPracticallySame(-norm2[0]) && Normal[1].IsPracticallySame(-norm2[1]) &&
                //    Normal[2].IsPracticallySame(-norm2[2])) segmentBool = true; //All points intersect
                if (segmentBool)
                {
                    //The arc should be on the arc list.
                    ArcList.Add(arc);
                }

                //Find points of intersection between two planes
                var position1 = Normal.crossProduct(norm2).normalize(3);
                var position2 = new[] { -position1[0], -position1[1], -position1[2] };
                var vertices  = new[] { position1, position2 };
                //Check to see if the intersection is on the arc. We already know it is on the great circle.
                for (var i = 0; i < 2; i++)
                {
                    var l1    = arc.ArcLength;
                    var l2    = ArcLength(arc.Nodes[0].Vector, vertices[i]);
                    var l3    = ArcLength(arc.Nodes[1].Vector, vertices[i]);
                    var total = l1 - l2 - l3;
                    if (Math.Abs(total) > 0.00001)
                    {
                        continue;
                    }
                    var node = arc.NextNodeAlongRotation(referenceArc.Direction);

                    //todo: NEED spherical distance along rotation. Below is an attempt
                    //Subtract the reference arc direction vector from the node and determine where it intersects the great circle
                    var theta = referenceArc.Direction[0] - node.Theta;
                    var phi   = referenceArc.Direction[1] - node.Phi;
                    var x     = Math.Cos(theta) * Math.Sin(phi);
                    var y     = Math.Sin(theta) * Math.Sin(phi);
                    var z     = Math.Cos(phi);
                    var point = new[] { x, y, z };
                    //Create two planes given the great circle and this new temporary arc
                    var tempNorm = point.crossProduct(node.Vector);
                    //Find points of intersection between two planes
                    var position3 = Normal.crossProduct(tempNorm).normalize(3);
                    var position4 = new[] { -position3[0], -position3[1], -position3[2] };
                    var vertices2 = new[] { position3, position4 };
                    for (var j = 0; j < 2; j++)
                    {
                        var tempL1    = ArcLength(node.Vector, point);
                        var tempL2    = ArcLength(node.Vector, vertices2[j]);
                        var tempL3    = ArcLength(point, vertices2[j]);
                        var tempTotal = tempL1 - tempL2 - tempL3;
                        if (Math.Abs(tempTotal) > 0.00001)
                        {
                            continue;
                        }
                        var intersection = new Intersection(node, tempL3, arc);
                        tempIntersections.Add(intersection);
                        ArcList.Add(arc);
                        break;
                    }
                    break;
                }
            }
            //Sort intersections
            var tempIntersections2 = tempIntersections.OrderBy(intersection => intersection.SphericalDistance).ToList();

            //Remove duplicates
            for (var i = 0; i < tempIntersections2.Count - 1; i++)
            {
                var intersection1 = tempIntersections2[i];
                var intersection2 = tempIntersections2[i + 1];
                if (intersection1.Node != intersection2.Node)
                {
                    Intersections.Add(intersection1);
                    //Add the last intersection to the list if it was no the same as the current
                    if (i == tempIntersections2.Count - 2)
                    {
                        Intersections.Add(intersection2);
                    }
                }
            }
            //Add the reference vertices to a list
            foreach (var arc in ArcList)
            {
                foreach (var referenceVertex in arc.ReferenceVertices)
                {
                    if (!ReferenceVertices.Contains(referenceVertex))
                    {
                        ReferenceVertices.Add(referenceVertex);
                    }
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     The volume of the bounding box.
        ///     Note that antipodal points would result in an infinite number of great circles, but can
        ///     be ignored since we are assuming the thickness of this solid is greater than 0.
        /// </summary>
        /// <param name="gaussianSphere">The gaussian sphere.</param>
        /// <param name="vector1">The vector1.</param>
        /// <param name="vector2">The vector2.</param>
        /// <param name="referenceArc">The reference arc.</param>
        internal GreatCircleAlongArc(GaussianSphere gaussianSphere, double[] vector1, double[] vector2, Arc referenceArc)
        {
            var antiPoint1 = new[] { -referenceArc.Nodes[0].X, -referenceArc.Nodes[0].Y, -referenceArc.Nodes[0].Z };

            //var antiPoint2 = new[] { -referenceArc.Nodes[1].X, -referenceArc.Nodes[1].Y, -referenceArc.Nodes[1].Z };
            ArcList       = new List <Arc>();
            Intersections = new List <Intersection>();
            var tempIntersections = new List <Intersection>();

            ReferenceVertices = new List <Vertex>();
            Normal            = vector1.crossProduct(vector2);
            foreach (var arc in gaussianSphere.Arcs)
            {
                if (arc == referenceArc)
                {
                    continue;
                }
                var segmentBool = false;
                //Create two planes given arc and the great circle
                var norm2 = arc.Nodes[0].Vector.crossProduct(arc.Nodes[1].Vector).normalize(3);
                //Check whether the planes are the same.
                if (Math.Abs(Normal[0] - norm2[0]) < 0.0001 && Math.Abs(Normal[1] - norm2[1]) < 0.0001 &&
                    Math.Abs(Normal[2] - norm2[2]) < 0.0001)
                {
                    segmentBool = true; //All points intersect
                }
                if (Math.Abs(Normal[0] + norm2[0]) < 0.0001 && Math.Abs(Normal[1] + norm2[1]) < 0.0001 &&
                    Math.Abs(Normal[2] + norm2[2]) < 0.0001)
                {
                    segmentBool = true; //All points intersect
                }
                //if (Normal[0].IsPracticallySame(norm2[0]) && Normal[1].IsPracticallySame(norm2[1]) &&
                //    Normal[2].IsPracticallySame(norm2[2])) segmentBool = true; //All points intersect
                //Check whether the planes are the same, but built with opposite normals.
                //if (Normal[0].IsPracticallySame(-norm2[0]) && Normal[1].IsPracticallySame(-norm2[1]) &&
                //    Normal[2].IsPracticallySame(-norm2[2])) segmentBool = true; //All points intersect
                //Set the intersection vertices
                double[][] vertices;
                if (segmentBool)
                {
                    vertices = new[] { arc.Nodes[0].Vector, arc.Nodes[1].Vector };
                }
                else
                {
                    //Find points of intersection between two planes
                    var position1 = Normal.crossProduct(norm2).normalize(3);
                    var position2 = new[] { -position1[0], -position1[1], -position1[2] };
                    vertices = new[] { position1, position2 };
                }


                for (var i = 0; i < 2; i++)
                {
                    double l1;
                    double l2;
                    double l3;
                    //If not on the same plane, check to see if intersection is on arc.
                    if (!segmentBool)
                    {
                        l1 = arc.ArcLength;
                        l2 = ArcLength(arc.Nodes[0].Vector, vertices[i]);
                        l3 = ArcLength(arc.Nodes[1].Vector, vertices[i]);

                        //Check to see if the intersection is on the arc. We already know it is on the great circle.
                        //It is ok if the vertex == the node.Vector.
                        var total = l1 - l2 - l3;
                        if ((l2.IsNegligible() && l3.IsNegligible()) || Math.Abs(total) > 0.00001)
                        {
                            continue; //Go to next.
                        }
                    }
                    var intersectionVertex = new Vertex(vertices[i]);

                    //Find distance from the reference arc's antipodal point 1 in direction of the reference arc.
                    l1 = referenceArc.ArcLength;
                    l2 = Math.PI - referenceArc.ArcLength;
                    l3 = ArcLength(referenceArc.Nodes[0].Vector, vertices[i]);
                    var          l4 = ArcLength(referenceArc.Nodes[1].Vector, vertices[i]);
                    var          l5 = ArcLength(antiPoint1, vertices[i]);
                    Intersection intersection;

                    //Case 1: Inbetween point1 and point2
                    var total1 = l1 - l3 - l4;
                    //Case 2: Inbetween point2 and antiPoint1
                    var total2 = l2 - l4 - l5;
                    if (Math.Abs(total1) < 0.00001 || Math.Abs(total2) < 0.00001)
                    {
                        intersection = new Intersection(intersectionVertex, l3, arc);
                        tempIntersections.Add(intersection);
                        continue;
                    }
                    //Case 3: Inbetween antiPoint1 and antiPoint2
                    //Case 4: Inbetween antiPoint2 and Point1
                    intersection = new Intersection(intersectionVertex, Constants.TwoPi - l3, arc);
                    tempIntersections.Add(intersection);

                    //Only one intersection is possible per arc, since the case of multiple intersections is captured above.
                    break;
                }
            }
            var tempIntersections2 = tempIntersections.OrderBy(intersection => intersection.SphericalDistance).ToList();

            //Remove duplicates
            for (var i = 0; i < tempIntersections2.Count - 1; i++)
            {
                var intersection1 = tempIntersections2[i];
                var intersection2 = tempIntersections2[i + 1];
                if (Math.Abs(intersection1.SphericalDistance - intersection2.SphericalDistance) > 0.00001)
                {
                    Intersections.Add(intersection1);
                }
                //Add the last intersection to the list if it was no the same as the current
                if (i == tempIntersections2.Count - 2)
                {
                    Intersections.Add(intersection2);
                }
            }
        }