Ejemplo n.º 1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="spherePos"></param>
        /// <param name="sphereRadius"></param>
        /// <param name="linePos"></param>
        /// <param name="LineDir"></param>
        /// <returns></returns>
        internal static intersectionFigData SphereLineIntersection(Vector3 spherePos, float sphereRadius, Vector3 linePos, Vector3 lineDir)
        {
            Vector3 planeNorm = Vector3.right;

            if (Vector3.Cross(planeNorm, Vector3.right).magnitude == 0)
            {
                planeNorm = Vector3.up;
            }
            planeNorm = Vector3.Cross(planeNorm, lineDir);
            planeNorm = planeNorm / planeNorm.magnitude;

            intersectionFigData intersectData = SpherePlaneIntersection(spherePos, sphereRadius, planeNorm, linePos);

            if (intersectData.figtype == GeoObjType.circle)
            {
                //circle is produced, check against line.
                return(CircleLineIntersection(linePos, lineDir, intersectData.vectordata[0], intersectData.vectordata[1], intersectData.floatdata[0]));
            }
            else
            {
                //no intersection
                return(new intersectionFigData()
                {
                    figtype = GeoObjType.none
                });
            }
        }
Ejemplo n.º 2
0
        private MasterGeoObj[] checkSphereSphere(AbstractSphere abstractSphere1, AbstractSphere abstractSphere2)
        {
            intersectionFigData data = IntersectionMath.SphereSphereIntersection(abstractSphere1, abstractSphere2);

            Debug.Log("Data produces " + data.figtype.ToString());
            Debug.Log("Point Value " + data.vectordata[0].ToString());

            MasterGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.circle)
            {
                DependentPoint centerPoint     = GeoObjConstruction.dPoint(data.vectordata[0]);
                Vector3        radiusDirection = Vector3.up;
                if (Vector3.Cross(radiusDirection, data.vectordata[1]).magnitude == 0)
                {
                    radiusDirection = Vector3.right;
                }
                radiusDirection = Vector3.Cross(data.vectordata[1], radiusDirection).normalized;

                DependentPoint  edgePoint = GeoObjConstruction.dPoint(data.vectordata[2]);
                DependentCircle newCircle = GeoObjConstruction.dCircle(centerPoint, edgePoint, data.vectordata[1]);
                mgoResult = new MasterGeoObj[] { centerPoint.setIntersectionFigure(0), edgePoint.setIntersectionFigure(0), newCircle.setIntersectionFigure(0) };
            }
            else if (data.figtype == GeoObjType.point)
            {
                mgoResult = new MasterGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]) };
            }
            return(mgoResult);
        }
Ejemplo n.º 3
0
        private void updateSphereLine(MasterGeoObj mgo, MasterGeoObj masterGeoObj1, MasterGeoObj masterGeoObj2)
        {
            intersectionFigData data = IntersectionMath.SphereLineIntersection(masterGeoObj1.GetComponent <AbstractSphere>(), masterGeoObj2.GetComponent <straightEdgeBehave>());

            if (data.figtype == mgo.figType)
            {
                //point or points;
                if (data.vectordata.Length > 1)
                {
                    mgo.Position3 = data.vectordata[mgo.intersectionMultipleIDX];
                }
                else
                {
                    mgo.Position3 = data.vectordata[0];
                }
            }
            else if (data.figtype == GeoObjType.none)
            {
                mgo.DeleteGeoObj();
            }
            else
            {
                Debug.LogWarning("TYPE MISMATCH");
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Finds the intersection of two circles
        /// </summary>
        /// <param name="center1">Center of the first circle</param>
        /// <param name="center2">Center of the second circle</param>
        /// <param name="norm1">Normal direction of theh first circle</param>
        /// <param name="norm2">Normal direction of the second circle</param>
        /// <param name="r1">radius of circle 1</param>
        /// <param name="r2">radisu of circle 2</param>
        /// <returns></returns>
        internal static intersectionFigData CircleCircleIntersection(Vector3 center1, Vector3 center2, Vector3 norm1, Vector3 norm2, float r1, float r2)
        {
            //begin by finding the circle of intersection of two spheres with same center and radius
            intersectionFigData circleFromSpheres = SphereSphereIntersection(center1, center2, r1, r2);

            circleFromSpheres.printFigDataToDebug();

            Vector3 q = circleFromSpheres.vectordata[0];
            //Debug.Log(q);
            Vector3 nu = circleFromSpheres.vectordata[1];
            //Debug.Log(q);
            float r = circleFromSpheres.floatdata[0];
            //Debug.Log(r);

            //intersection of the plane defined by the first circle and the plane defined by the circle producted in the sphere sphere intersection.
            intersectionFigData data2 = PlanePlaneIntersection(q, nu, center1, norm1);

            Vector3[] lineData = data2.vectordata;

            //intersection of the line from plane plane and the circle formt he sphere sphere.
            intersectionFigData data3 = CircleLineIntersection(lineData[0], lineData[1], q, nu, r);

            data3.printFigDataToDebug();
            return(data3);
        }
Ejemplo n.º 5
0
        private MasterGeoObj[] checkSphereFlatface(AbstractSphere abstractSphere, flatfaceBehave flatfaceBehave)
        {
            intersectionFigData data = IntersectionMath.SpherePlaneIntersection(abstractSphere, flatfaceBehave);

            MasterGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.circle)
            {
                DependentPoint centerPoint     = GeoObjConstruction.dPoint(data.vectordata[0]);
                Vector3        radiusDirection = Vector3.up;
                if (Vector3.Cross(radiusDirection, data.vectordata[1]).magnitude == 0)
                {
                    radiusDirection = Vector3.right;
                }
                radiusDirection = Vector3.Cross(data.vectordata[1], radiusDirection).normalized;

                DependentPoint  edgePoint = GeoObjConstruction.dPoint(data.vectordata[0] + data.floatdata[0] * radiusDirection);
                DependentCircle newCircle = GeoObjConstruction.dCircle(centerPoint, edgePoint, data.vectordata[1]);
                mgoResult = new MasterGeoObj[] { centerPoint.setIntersectionFigure(0), edgePoint.setIntersectionFigure(1), newCircle.setIntersectionFigure(2) };
            }
            else if (data.figtype == GeoObjType.point)
            {
                mgoResult = new MasterGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]) };
            }
            return(mgoResult);
        }
Ejemplo n.º 6
0
        private MasterGeoObj[] checkFlatfaceStraightedge(flatfaceBehave flatfaceBehave, straightEdgeBehave straightEdgeBehave)
        {
            intersectionFigData data = IntersectionMath.LinePlaneIntersection(flatfaceBehave, straightEdgeBehave);

            MasterGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.point)
            {
                mgoResult = new MasterGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0) };
            }
            return(mgoResult);
        }
Ejemplo n.º 7
0
        private AbstractGeoObj[] checkStraightedgeStraightedge(straightEdgeBehave straightEdgeBehave1, straightEdgeBehave straightEdgeBehave2)
        {
            intersectionFigData data = IntersectionMath.LineLineIntersection(straightEdgeBehave1, straightEdgeBehave2);

            AbstractGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.point)
            {
                mgoResult = new AbstractGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0) };
            }
            return(mgoResult);
        }
Ejemplo n.º 8
0
        private MasterGeoObj[] checkFlatfaceFlatface(flatfaceBehave flatfaceBehave1, flatfaceBehave flatfaceBehave2)
        {
            intersectionFigData data = IntersectionMath.PlanePlaneIntersection(flatfaceBehave1, flatfaceBehave2);

            MasterGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.line)
            {
                Debug.LogWarning("Need to Construct Line");
            }
            return(mgoResult);
        }
Ejemplo n.º 9
0
        internal static intersectionFigData SegmentPlaneIntersection(Vector3 linePos1, Vector3 linePos2, Vector3 planePos, Vector3 planeNorm)
        {
            intersectionFigData canidates = LinePlaneIntersection(linePos1, (linePos1 - linePos2).normalized, planePos, planeNorm);

            //for some reason this condition works with the UNit checker but fails in the Shearing scene???  No result when there definately should be one.
            //temp fix.  use LinePlane intersection in Shearing scene.
            if (canidates.figtype == GeoObjType.point && (canidates.vectordata[0] - linePos1).magnitude + (canidates.vectordata[0] - linePos2).magnitude - (linePos1 - linePos2).magnitude < .001f)
            {
                return(canidates);
            }
            else
            {
                return(new intersectionFigData {
                    figtype = GeoObjType.none
                });
            }
        }
Ejemplo n.º 10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="circlePos"></param>
        /// <param name="circleNorm"></param>
        /// <param name="radius"></param>
        /// <param name="planePos"></param>
        /// <param name="planeNorm"></param>
        /// <returns></returns>
        internal static intersectionFigData CirclePlaneIntersection(Vector3 circlePos, Vector3 circleNorm, float circleRadius, Vector3 planePos, Vector3 planeNorm)
        {
            intersectionFigData figDat = PlanePlaneIntersection(circlePos, circleNorm, planePos, planeNorm);

            Vector3[] lineData = figDat.vectordata;
            if (figDat.figtype == GeoObjType.line)
            {
                return(CircleLineIntersection(lineData[0], lineData[1], circlePos, circleNorm, circleRadius));
            }
            else
            {
                return(new intersectionFigData()
                {
                    figtype = GeoObjType.none
                });
            }
        }
Ejemplo n.º 11
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="spherePos"></param>
        /// <param name="sphereRadius"></param>
        /// <param name="circlePos"></param>
        /// <param name="circleNorm"></param>
        /// <param name="circleRadius"></param>
        /// <returns></returns>
        internal static intersectionFigData SphereCircleIntersection(Vector3 spherePos, float sphereRadius, Vector3 circlePos, Vector3 circleNorm, float circleRadius)
        {
            intersectionFigData planeSphere = SpherePlaneIntersection(spherePos, sphereRadius, circleNorm, circlePos);

            if (planeSphere.figtype == GeoObjType.circle)
            {
                return(CircleCircleIntersection(planeSphere.vectordata[0], circlePos, planeSphere.vectordata[1], circleNorm, planeSphere.floatdata[0], circleRadius));
            }
            else
            {
                //no intersection
                return(new intersectionFigData()
                {
                    figtype = GeoObjType.none
                });
            }
        }
Ejemplo n.º 12
0
        private AbstractGeoObj[] checkSpherecircle(AbstractSphere abstractSphere, AbstractCircle abstractCircle)
        {
            intersectionFigData data = IntersectionMath.SphereCircleIntersection(abstractSphere, abstractCircle);

            AbstractGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.point)
            {
                if (data.vectordata.Length == 1)
                {
                    mgoResult = new AbstractGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0) };
                }
                else if (data.vectordata.Length == 2)
                {
                    mgoResult = new AbstractGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0), GeoObjConstruction.dPoint(data.vectordata[1]).setIntersectionFigure(1) };
                }
            }
            return(mgoResult);
        }
Ejemplo n.º 13
0
        private MasterGeoObj[] CheckCircleCircle(AbstractCircle abstractCircle1, AbstractCircle abstractCircle2)
        {
            intersectionFigData data = IntersectionMath.CircleCircleIntersection(abstractCircle1, abstractCircle2);

            MasterGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.point)
            {
                if (data.vectordata.Length == 1)
                {
                    mgoResult = new MasterGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0) };
                }
                else if (data.vectordata.Length == 2)
                {
                    mgoResult = new MasterGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0), GeoObjConstruction.dPoint(data.vectordata[1]).setIntersectionFigure(1) };
                }
            }
            return(mgoResult);
        }
Ejemplo n.º 14
0
        private MasterGeoObj[] checkSphereStraightEdge(AbstractSphere abstractSphere, straightEdgeBehave straightEdgeBehave)
        {
            intersectionFigData data = IntersectionMath.SphereLineIntersection(abstractSphere, straightEdgeBehave);

            MasterGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.point)
            {
                if (data.vectordata.Length == 1)
                {
                    mgoResult = new MasterGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0) };
                }
                else if (data.vectordata.Length == 2)
                {
                    mgoResult = new MasterGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0), GeoObjConstruction.dPoint(data.vectordata[1]).setIntersectionFigure(1) };
                }
            }
            return(mgoResult);
        }
Ejemplo n.º 15
0
        private AbstractGeoObj[] checkCircleFlatface(AbstractCircle abstractCircle, flatfaceBehave flatfaceBehave)
        {
            intersectionFigData data = IntersectionMath.CirclePlaneIntersection(abstractCircle, flatfaceBehave);

            AbstractGeoObj[] mgoResult = null;
            if (data.figtype == GeoObjType.point)
            {
                if (data.vectordata.Length == 1)
                {
                    mgoResult = new AbstractGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0) };
                }
                else if (data.vectordata.Length == 2)
                {
                    mgoResult = new AbstractGeoObj[] { GeoObjConstruction.dPoint(data.vectordata[0]).setIntersectionFigure(0), GeoObjConstruction.dPoint(data.vectordata[1]).setIntersectionFigure(1) };
                }
            }
            return(mgoResult);
        }
Ejemplo n.º 16
0
        private void updatePlaneLine(AbstractGeoObj mgo, AbstractGeoObj AbstractGeoObj1, AbstractGeoObj AbstractGeoObj2)
        {
            intersectionFigData data = IntersectionMath.LinePlaneIntersection(AbstractGeoObj1.GetComponent <flatfaceBehave>(), AbstractGeoObj2.GetComponent <straightEdgeBehave>());

            if (data.figtype == mgo.figType)
            {
                //point only option;
                mgo.Position3 = data.vectordata[0];
                mgo.AddToRManager();
            }
            else if (data.figtype == GeoObjType.none)
            {
                mgo.DeleteGeoObj();
            }
            else
            {
                Debug.LogWarning("TYPE MISMATCH");
            }
        }
Ejemplo n.º 17
0
        private void updatePlanePlane(MasterGeoObj mgo, MasterGeoObj masterGeoObj1, MasterGeoObj masterGeoObj2)
        {
            intersectionFigData data = IntersectionMath.PlanePlaneIntersection(masterGeoObj1.GetComponent <flatfaceBehave>(), masterGeoObj2.GetComponent <flatfaceBehave>());

            if (data.figtype == mgo.figType)
            {
                //line only option
                mgo.Position3 = data.vectordata[0];
                mgo.AddToRManager();
            }
            else if (data.figtype == GeoObjType.none)
            {
                mgo.DeleteGeoObj();
            }
            else
            {
                Debug.LogWarning("TYPE MISMATCH");
            }
        }
Ejemplo n.º 18
0
        /// <summary>
        /// Finds the intersection between two planes
        /// </summary>
        /// <param name="pos1">Point on plane 1</param>
        /// <param name="norm1">Normal direction of plane1</param>
        /// <param name="pos2">Point on plane 2</param>
        /// <param name="norm2">Normal direction of plane 2</param>
        /// <returns></returns>
        internal static intersectionFigData PlanePlaneIntersection(Vector3 pos1, Vector3 norm1, Vector3 pos2, Vector3 norm2)
        {
            Vector3 lineDirection = Vector3.Cross(norm1, norm2);

            //instead find a line on the plane1 that intersects plane 2
            Vector3 crossInput = Vector3.right;

            if (Vector3.Cross(crossInput, norm1).magnitude == 0)
            {
                crossInput = Vector3.up;
            }

            Vector3 tLineDir = Vector3.Cross(crossInput, norm1);

            if (Vector3.Dot(tLineDir, norm2) == 0)
            {
                crossInput = Vector3.forward;
                tLineDir   = Vector3.Cross(crossInput, norm1);
            }
            //then use line line

            intersectionFigData figDataTemp = LinePlaneIntersection(pos1, tLineDir, pos2, norm2);

            figDataTemp.printFigDataToDebug();

            if (lineDirection.magnitude > 0 && figDataTemp.figtype == GeoObjType.point)
            {
                Vector3 linePosition = figDataTemp.vectordata[0];
                return(new intersectionFigData {
                    vectordata = new Vector3[2] {
                        linePosition, lineDirection
                    }, figtype = GeoObjType.line
                });
            }
            else
            {
                return(new intersectionFigData {
                    figtype = GeoObjType.none
                });
            }
        }
Ejemplo n.º 19
0
        private void updateCircleLine(MasterGeoObj mgo, MasterGeoObj masterGeoObj1, MasterGeoObj masterGeoObj2)
        {
            intersectionFigData data = IntersectionMath.CircleLineIntersection(masterGeoObj1.GetComponent <AbstractCircle>(), masterGeoObj2.GetComponent <straightEdgeBehave>());

            if (data.figtype == mgo.figType)
            {
                switch (data.figtype)
                {
                case GeoObjType.point:
                    mgo.Position3 = data.vectordata[0];
                    mgo.AddToRManager();
                    break;

                case GeoObjType.circle:
                    DependentCircle circle = mgo.GetComponent <DependentCircle>();
                    circle.centerPos        = data.vectordata[0];
                    circle.normalDir        = data.vectordata[1];
                    circle.center.Position3 = data.vectordata[0];
                    circle.edgePos          = data.vectordata[2];
                    circle.edge.Position3   = data.vectordata[2];
                    circle.AddToRManager();
                    circle.edge.AddToRManager();
                    circle.center.AddToRManager();
                    break;

                default:
                    break;
                }
            }
            else if (data.figtype == GeoObjType.none)
            {
                mgo.DeleteGeoObj();
            }
            else
            {
                Debug.LogWarning("TYPE MISMATCH");
            }
        }
Ejemplo n.º 20
0
        private void updateCirclePlane(MasterGeoObj mgo, MasterGeoObj masterGeoObj1, MasterGeoObj masterGeoObj2)
        {
            intersectionFigData data = IntersectionMath.CirclePlaneIntersection(masterGeoObj1.GetComponent <AbstractCircle>(), masterGeoObj2.GetComponent <flatfaceBehave>());

            if (data.figtype == mgo.figType)
            {
                if (data.vectordata.Length > 1)
                {
                    mgo.Position3 = data.vectordata[mgo.intersectionMultipleIDX];
                }
                else
                {
                    mgo.Position3 = data.vectordata[0];
                }
            }
            else if (data.figtype == GeoObjType.none)
            {
                mgo.DeleteGeoObj();
            }
            else
            {
                Debug.LogWarning("TYPE MISMATCH");
            }
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Finds the intersection of two spheres
        /// </summary>
        /// <param name="c">Center1</param>
        /// <param name="p">Center2</param>
        /// <param name="r1">Radius 1</param>
        /// <param name="r2">Radidus 2</param>
        /// <returns></returns>
        internal static intersectionFigData SphereSphereIntersection(Vector3 c, Vector3 p, float r1, float r2)
        {
            //distance between spheres
            Vector3 d = p - c;


            // sum of the radii			NEVER USED
            //float R = r1 + r2;

            float x = (r1 * r1 - r2 * r2 - d.magnitude * d.magnitude) / (-2f * d.magnitude);
            float h = Mathf.Sqrt(r1 * r1 - x * x);

            if (h != Mathf.Sqrt(r2 * r2 - (d.magnitude - x) * (d.magnitude - x)))
            {
                Debug.LogWarning("Symmetry Broke");
            }

            //float h = Mathf.Sqrt((4 * r1 * r1 + d.magnitude * d.magnitude - Mathf.Pow(r1 * r1 - r2 * r2 + d.magnitude * d.magnitude, 2) / (4 * d.magnitude * d.magnitude)));
            //float h = 0.5f * Mathf.Sqrt(d.magnitude * d.magnitude - r1 * r1 - r2 * r2);

            //if(r1 < h || d.magnitude < r1 || d.magnitude < r2)
            if (r1 < h)
            {
                Debug.LogWarning("Houstain, we have a problem");
            }

            //normal of the circle
            Vector3 v = d.normalized;

            //point of tangency.
            Vector3 q = c + r1 * v;

            //vector perpendicular to the normal
            Vector3 nu = Vector3.up;

            if (Vector3.Cross(nu, v).magnitude == 0)
            {
                nu = Vector3.forward;
            }
            nu = Vector3.Cross(nu, v).normalized;

            //center of circle
            Vector3 newCenter = c + Mathf.Sqrt(r1 * r1 - h * h) * v;

            //point on circle.
            Vector3 u = newCenter + h * nu;

            //cases with a solution.
            if (d.magnitude == r1 + r2)
            {
                //the spheres are tangential and neither sphere is insdie the other.
                intersectionFigData point1 = new intersectionFigData();
                point1.figtype    = GeoObjType.point;
                point1.vectordata = new Vector3[] { q };
                return(point1);
            }
            else if (d.magnitude == Mathf.Abs(r1 - r2))
            {
                //the spheres are tangential and one sphere is inside the other.
                intersectionFigData point2 = new intersectionFigData();
                point2.figtype    = GeoObjType.point;
                point2.vectordata = new Vector3[] { q };
                return(point2);
            }
            else if (Mathf.Abs(r1 - r2) < d.magnitude && d.magnitude < r1 + r2)
            {
                //the spheres intersect making a cirlce on both spheres.
                intersectionFigData circle1 = new intersectionFigData();
                circle1.vectordata = new Vector3[] { newCenter, v, u };
                circle1.figtype    = GeoObjType.circle;
                circle1.floatdata  = new float[] { (newCenter - u).magnitude };
                return(circle1);
            }
            else
            {
                return(new intersectionFigData {
                    figtype = GeoObjType.none
                });
                //there is no solution.
            }
        }
Ejemplo n.º 22
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="linePos"></param>
        /// <param name="lineDirection"></param>
        /// <param name="circlePos"></param>
        /// <param name="circleNorm"></param>
        /// <param name="circleRadius"></param>
        /// <returns></returns>
        internal static intersectionFigData CircleLineIntersection(Vector3 linePos, Vector3 lineDirection, Vector3 circlePos, Vector3 circleNorm, float circleRadius)
        {
            //careful of rounding.  this caused mysery for months.
            if (Vector3.Dot(lineDirection, circleNorm) == 0 && Vector3.Project(linePos - circlePos, circleNorm).magnitude < .00001)
            {
                //if the line is coplanar with the circle

                //start by definingg a basis system to move into 2-space.
                Vector3 basis1 = Vector3.right;

                if (Vector3.Cross(Vector3.right, circleNorm).magnitude == 0)
                {
                    basis1 = Vector3.up;
                }

                basis1 = Vector3.ProjectOnPlane(basis1, circleNorm);
                Vector3 basis2 = Vector3.Cross(circleNorm, basis1);
                Vector3.OrthoNormalize(ref circleNorm, ref basis1, ref basis2);

                float x1 = Vector3.Dot(linePos - circlePos, basis1);
                float y1 = Vector3.Dot(linePos - circlePos, basis2);

                float x2 = Vector3.Dot(linePos + lineDirection - circlePos, basis1);
                float y2 = Vector3.Dot(linePos + lineDirection - circlePos, basis2);

                float deltax      = x2 - x1;
                float deltay      = y2 - y1;
                float deltar      = Mathf.Sqrt(deltax * deltax + deltay * deltay);
                float determinant = x1 * y2 - y1 * x2;

                float discriminant     = circleRadius * circleRadius * deltar * deltar - determinant * determinant;
                float rootDiscriminant = Mathf.Sqrt(discriminant);

                if (discriminant == 0)
                {
                    //intersects at one point.
                    float x5 = (determinant * deltay) / (deltar * deltar);
                    float y5 = (-determinant * deltax) / (deltar * deltar);

                    Vector3 position = x5 * basis1 + y5 * basis2 + circlePos;

                    return(new intersectionFigData()
                    {
                        figtype = GeoObjType.point, vectordata = new Vector3[] { position }
                    });
                }
                else if (discriminant > 0)
                {
                    //intersects at two points.
                    float   x3        = (determinant * deltay + Mathf.Sign(deltay) * deltax * rootDiscriminant) / (deltar * deltar);
                    float   y3        = (-determinant * deltax + Mathf.Abs(deltay) * rootDiscriminant) / (deltar * deltar);
                    Vector3 position1 = x3 * basis1 + y3 * basis2 + circlePos;

                    float   x4        = (determinant * deltay - Mathf.Sign(deltay) * deltax * rootDiscriminant) / (deltar * deltar);
                    float   y4        = (-determinant * deltax - Mathf.Abs(deltay) * rootDiscriminant) / (deltar * deltar);
                    Vector3 position2 = x4 * basis1 + y4 * basis2 + circlePos;

                    //two points are returned.
                    return(new intersectionFigData()
                    {
                        figtype = GeoObjType.point, vectordata = new Vector3[] { position1, position2 }, floatdata = new float[] { 2f }
                    });
                }
                else
                {
                    return(new intersectionFigData()
                    {
                        figtype = GeoObjType.none
                    });
                    //intersects at no points.
                }
            }
            else if (Vector3.Dot(lineDirection, circleNorm) == 0 && Vector3.Project(linePos - circlePos, circleNorm).magnitude > 0)
            {
                //if the line is noncoplanar with the circle and not parallel - parallel case would go above
                //Vector3 pos = linePos + ((Vector3.Dot(circleNorm, circlePos) - Vector3.Dot(circleNorm, linePos)) / (Vector3.Dot(circleNorm, lineDirection))) * lineDirection;
                //return new intersectionFigData { figtype = GeoObjType.point, vectordata = new Vector3[] { pos } };

                //check plane line and then check if on circle.
                intersectionFigData pl = LinePlaneIntersection(linePos, lineDirection, circlePos, circleNorm);
                if (pl.figtype == GeoObjType.none || (pl.figtype == GeoObjType.point && Vector3.Distance(pl.vectordata[0], circlePos) == circleRadius))
                {
                    return(pl);
                }
                else
                {
                    return(new intersectionFigData()
                    {
                        figtype = GeoObjType.none
                    });
                }
            }
            else
            {
                return(new intersectionFigData()
                {
                    figtype = GeoObjType.none
                });
            }
        }