/// <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 }); } }
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); }
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"); } }
/// <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); }
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); }
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); }
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); }
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); }
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 }); } }
/// <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 }); } }
/// <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 }); } }
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); }
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); }
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); }
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); }
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"); } }
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"); } }
/// <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 }); } }
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"); } }
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"); } }
/// <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. } }
/// <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 }); } }