public CanSeeEdge (Edge e) {
			edge = e;
			canSeeA = true;
			canSeeB = true;
		}
		public Edge Merge (Edge rhs) {
			//this.borderA = (this.borderA || rhs.borderA);
			//this.borderB = (this.borderB || rhs.borderB);
			return this;
		}
		public float NearestPointOnEdges (Edge e2) {
			return NearestPointsOnEdges (this,e2).x;
		}
		public static Vector2 NearestPointsOnEdges (Edge e1, Edge e2) {
		    Vector3   u = e1.endPointB - e1.endPointA;
		    Vector3   v = e2.endPointB - e2.endPointA;
		    Vector3   w = e1.endPointA - e2.endPointA;
		    float    a = Vector3.Dot(u,u);        // always >= 0
		    float    b = Vector3.Dot(u,v);
		    float    c = Vector3.Dot(v,v);        // always >= 0
		    float    d = Vector3.Dot(u,w);
		    float    e = Vector3.Dot(v,w);
		    float    D = a*c - b*b;       // always >= 0
		    float    sc, sN, sD = D;      // sc = sN / sD, default sD = D >= 0
		    float    tc, tN, tD = D;      // tc = tN / tD, default tD = D >= 0
		
		    // compute the line parameters of the two closest points
		    if (D < 0.05F) { // the lines are almost parallel
		        sN = 0.0F;        // force using point P0 on segment S1
		        sD = 1.0F;        // to prevent possible division by 0.0 later
		        tN = e;
		        tD = c;
		    }
		    else {                // get the closest points on the infinite lines
		        sN = (b*e - c*d);
		        tN = (a*e - b*d);
		        if (sN < 0.0F) {       // sc < 0 => the s=0 edge is visible
		            sN = 0.0F;
		            tN = e;
		            tD = c;
		        }
		        else if (sN > sD) {  // sc > 1 => the s=1 edge is visible
		            sN = sD;
		            tN = e + b;
		            tD = c;
		        }
		    }
		
		    if (tN < 0.0F) {           // tc < 0 => the t=0 edge is visible
		        tN = 0.0F;
		        // recompute sc for this edge
		        if (-d < 0.0F)
		            sN = 0.0F;
		        else if (-d > a)
		            sN = sD;
		        else {
		            sN = -d;
		            sD = a;
		        }
		    }
		    else if (tN > tD) {      // tc > 1 => the t=1 edge is visible
		        tN = tD;
		        // recompute sc for this edge
		        if ((-d + b) < 0.0F)
		            sN = 0;
		        else if ((-d + b) > a)
		            sN = sD;
		        else {
		            sN = (-d + b);
		            sD = a;
		        }
		    }
		    // finally do the division to get sc and tc
		    sc = (Mathf.Abs(sN) < 0.05F ? 0.0F : sN / sD);
		    tc = (Mathf.Abs(tN) < 0.05F ? 0.0F : tN / tD);
		
		    // get the difference of the two closest points
		    //Vector3   dP = w + (sc * u) - (tc * v);  // = S1(sc) - S2(tc)
		
		    return new Vector2 (sc,tc);   // return the closest distance
		}
		public static Vector2 IntersectionFactorFast (Edge memberEdge, Edge testEdge) {
			Vector2 memberEdgePointA = new Vector2(memberEdge.endPointA.x, memberEdge.endPointA.z);
			Vector2 memberEdgePointB = new Vector2(memberEdge.endPointB.x, memberEdge.endPointB.z);
			Vector2 testEdgePointA = new Vector2(testEdge.endPointA.x, testEdge.endPointA.z);
			Vector2 testEdgePointB = new Vector2(testEdge.endPointB.x, testEdge.endPointB.z);
	
			float Ax_Minus_Cx = memberEdgePointA.x - testEdgePointA.x;
			float Ay_Minus_Cy = memberEdgePointA.y - testEdgePointA.y;
	
	
			float Dx_Minus_Cx = testEdgePointB.x - testEdgePointA.x;
			float Dy_Minus_Cy = testEdgePointB.y - testEdgePointA.y;
	
			float Bx_Minus_Ax = memberEdgePointB.x - memberEdgePointA.x;
			float By_Minus_Ay = memberEdgePointB.y - memberEdgePointA.y;
	
			float numerator = (Ay_Minus_Cy * Dx_Minus_Cx) - (Ax_Minus_Cx * Dy_Minus_Cy);
			float denominator = (Bx_Minus_Ax * Dy_Minus_Cy) - (By_Minus_Ay * Dx_Minus_Cx);
	
			// if lines do not intersect, return now
			if (denominator == 0)
			{
				return new Vector2 (0,0);
			}
	
			float factorAB = numerator / denominator;
			float factorCD = ((Ay_Minus_Cy * Bx_Minus_Ax) - (Ax_Minus_Cx * By_Minus_Ay)) / denominator;
			
			return new Vector2 (factorAB,factorCD);
		}
		public static EdgeIntersection DoesLinesIntersect (Edge memberEdge, Edge testEdge) {
			Vector2 memberEdgePointA = new Vector2(memberEdge.endPointA.x, memberEdge.endPointA.z);
			Vector2 memberEdgePointB = new Vector2(memberEdge.endPointB.x, memberEdge.endPointB.z);
			Vector2 testEdgePointA = new Vector2(testEdge.endPointA.x, testEdge.endPointA.z);
			Vector2 testEdgePointB = new Vector2(testEdge.endPointB.x, testEdge.endPointB.z);
	
			float Ax_Minus_Cx = memberEdgePointA.x - testEdgePointA.x;
			float Ay_Minus_Cy = memberEdgePointA.y - testEdgePointA.y;
	
	
			float Dx_Minus_Cx = testEdgePointB.x - testEdgePointA.x;
			float Dy_Minus_Cy = testEdgePointB.y - testEdgePointA.y;
	
			float Bx_Minus_Ax = memberEdgePointB.x - memberEdgePointA.x;
			float By_Minus_Ay = memberEdgePointB.y - memberEdgePointA.y;
	
			float numerator = (Ay_Minus_Cy * Dx_Minus_Cx) - (Ax_Minus_Cx * Dy_Minus_Cy);
			float denominator = (Bx_Minus_Ax * Dy_Minus_Cy) - (By_Minus_Ay * Dx_Minus_Cx);
	
			// if lines do not intersect, return now
			if (denominator == 0)
			{
				return new EdgeIntersection (Vector3.zero,Vector3.zero,OnLinePosition.Paralell);
			}
	
			float factorAB = numerator / denominator;
			float factorCD = ((Ay_Minus_Cy * Bx_Minus_Ax) - (Ax_Minus_Cx * By_Minus_Ay)) / denominator;
	
			Vector3 intersectA = memberEdge.endPointA+(memberEdge.endPointB-memberEdge.endPointA)*factorAB;
			Vector3 intersectB = testEdge.endPointA+(testEdge.endPointB-testEdge.endPointA)*factorCD;
			
			//If the factor is less than 0 or greater than 1, then the nearest point is not on the line
			if (factorAB < 0) {
				return new EdgeIntersection (intersectA,intersectB,OnLinePosition.Left);
			} else if (factorAB > 1) {
				return new EdgeIntersection (intersectA,intersectB,OnLinePosition.Right);
			}
			
			return new EdgeIntersection (intersectA,intersectB,OnLinePosition.OnLine);
		}
		public static OnLinePosition DoesLinesIntersectFast (Edge memberEdge, Edge testEdge) {
			Vector2 memberEdgePointA = new Vector2(memberEdge.endPointA.x, memberEdge.endPointA.z);
			Vector2 memberEdgePointB = new Vector2(memberEdge.endPointB.x, memberEdge.endPointB.z);
			Vector2 testEdgePointA = new Vector2(testEdge.endPointA.x, testEdge.endPointA.z);
			Vector2 testEdgePointB = new Vector2(testEdge.endPointB.x, testEdge.endPointB.z);
	
			float Ax_Minus_Cx = memberEdgePointA.x - testEdgePointA.x;
			float Ay_Minus_Cy = memberEdgePointA.y - testEdgePointA.y;
	
	
			float Dx_Minus_Cx = testEdgePointB.x - testEdgePointA.x;
			float Dy_Minus_Cy = testEdgePointB.y - testEdgePointA.y;
	
			float Bx_Minus_Ax = memberEdgePointB.x - memberEdgePointA.x;
			float By_Minus_Ay = memberEdgePointB.y - memberEdgePointA.y;
	
			float numerator = (Ay_Minus_Cy * Dx_Minus_Cx) - (Ax_Minus_Cx * Dy_Minus_Cy);
			float denominator = (Bx_Minus_Ax * Dy_Minus_Cy) - (By_Minus_Ay * Dx_Minus_Cx);
	
			// if lines do not intersect, return now
			if (denominator == 0)
			{
				return OnLinePosition.Paralell;
			}
	
			float factorAB = numerator / denominator;
			
			//If the factor is less than 0 or greater than 1, then the nearest point is not on the line
			if (factorAB < 0) {
				return OnLinePosition.Left;
			} else if (factorAB > 1) {
				return OnLinePosition.Right;
			}
			
			return OnLinePosition.OnLine;
		}
		public static EdgeIntersection IntersectionTest(Edge memberEdge, Edge testEdge)
		{
			Vector2 memberEdgePointA = new Vector2(memberEdge.endPointA.x, memberEdge.endPointA.z);
			Vector2 memberEdgePointB = new Vector2(memberEdge.endPointB.x, memberEdge.endPointB.z);
			Vector2 testEdgePointA = new Vector2(testEdge.endPointA.x, testEdge.endPointA.z);
			Vector2 testEdgePointB = new Vector2(testEdge.endPointB.x, testEdge.endPointB.z);
	
			float Ax_Minus_Cx = memberEdgePointA.x - testEdgePointA.x;
			float Ay_Minus_Cy = memberEdgePointA.y - testEdgePointA.y;
	
	
			float Dx_Minus_Cx = testEdgePointB.x - testEdgePointA.x;
			float Dy_Minus_Cy = testEdgePointB.y - testEdgePointA.y;
	
			float Bx_Minus_Ax = memberEdgePointB.x - memberEdgePointA.x;
			float By_Minus_Ay = memberEdgePointB.y - memberEdgePointA.y;
	
			float numerator = (Ay_Minus_Cy * Dx_Minus_Cx) - (Ax_Minus_Cx * Dy_Minus_Cy);
			float denominator = (Bx_Minus_Ax * Dy_Minus_Cy) - (By_Minus_Ay * Dx_Minus_Cx);
	
			// if lines do not intersect, return now
			if (denominator == 0)
			{
				if (numerator == 0)
				{
					return new EdgeIntersection (LineClassification.Collinear);
				}
	
				// Debug.Log("Intersect Reuslt	\t" + LineClassification.Paralell);
				return new EdgeIntersection (LineClassification.Paralell);
			}
	
			float factorAB = numerator / denominator;
			float factorCD = ((Ay_Minus_Cy * Bx_Minus_Ax) - (Ax_Minus_Cx * By_Minus_Ay)) / denominator;
	
			Vector3 intersectA = memberEdge.endPointA+(memberEdge.endPointB-memberEdge.endPointA)*factorAB;
			Vector3 intersectB = testEdge.endPointA+(testEdge.endPointB-testEdge.endPointA)*factorCD;
			
			//Debug.DrawRay (memberEdge.endPointA+(memberEdge.endPointB-memberEdge.endPointA)*factorAB,Vector3.up*3,Color.red);
			//Debug.DrawRay (testEdge.endPointA+(testEdge.endPointB-testEdge.endPointA)*factorCD,Vector3.up*2,Color.blue);
			//now determine the type of intersection
			if ((factorAB >= 0f) && (factorAB <= 1f) && (factorCD >= 0f) && (factorCD <= 1f))
			{
				//Debug.Log("Intersect Reuslt	\t" + LineClassification.SegmentIntersect);
				return new EdgeIntersection (LineClassification.SegmentIntersect,intersectA,intersectB);
	
			}
			else if ((factorCD >= 0f) && (factorCD <= 1f))
			{
				//Debug.Log("Intersect Reuslt	\t" + LineClassification.A_BISECTS_B);
				return new EdgeIntersection (LineClassification.A_BISECTS_B,intersectA,intersectB);
			}
			else if ((factorAB >= 0f) && (factorAB <= 1.0f))
			{
				//Debug.Log("Intersect Reuslt	\t" + LineClassification.B_BISECTS_A);
				return new EdgeIntersection (LineClassification.B_BISECTS_A,intersectA,intersectB);
			}
	
			//Debug.Log("Intersect Reuslt	\t" + LineClassification.LinesIntersect);
			return new EdgeIntersection (LineClassification.LinesIntersect,intersectA,intersectB);
	
		}
		public Edge TurningRadius (float rad) {
			Edge e1;
			
			//if (borderA || borderB) {
				float magn = edgeVector3D.magnitude;
				Vector3 norm = edgeVector3D/magn;
				
				//if (borderA && borderB) {
					if (rad*2.0F >= magn) {
						//e1 = new Edge (center,center);
						e1 = new Edge (endPointA+edgeVector3D*0.45F,endPointB-edgeVector3D*0.45F);
					} else {
						e1 = new Edge (endPointA+norm*rad,endPointB-norm*rad);
					}
				//} else if (borderA) {
				//	e1 = new Edge (endPointA+norm*rad,endPointB);
				//} else {
				//	e1 = new Edge (endPointA,endPointB-norm*rad);
				//}
			//} else {
			//	e1 = new Edge (endPointA,endPointB);	
			//}
			return e1;
		}