} // End Property Slope // https://stackoverflow.com/questions/17692922/check-is-a-point-x-y-is-between-two-points-drawn-on-a-straight-line public bool IsPointOnLine(MyPoint2D <T> p) { T norm = this.Vector.MagnitudeSquared; MyVector2D <T> vec1 = new MyVector2D <T>(this.m_start, p); MyVector2D <T> vec2 = new MyVector2D <T>(this.m_end, p); T dist = Arithmetics <T> .Add(vec1.MagnitudeSquared, vec2.MagnitudeSquared); if (norm.Equals(dist)) { return(true); } T delta = Arithmetics <T> .Subtract(vec1.MagnitudeSquared, vec2.MagnitudeSquared); decimal decDelta = System.Convert.ToDecimal(delta); decDelta = System.Math.Abs(decDelta); // Greatest possible floating-point difference decimal decFloatEpsilon = System.Convert.ToDecimal(float.Epsilon); if (decDelta <= decFloatEpsilon) { return(true); } return(false); } // End Function IsPointOnLine
} // End Function IsPointOnLine public static MyVector2D <T> ToVector(MyPoint2D <T> start, MyPoint2D <T> end) { T x = Arithmetics <T> .Subtract(end.X, start.X); T y = Arithmetics <T> .Subtract(end.Y, start.Y); return(new MyVector2D <T>(x, y)); } // End Function ToVector
} // End Operator + public static MyPoint2D <T> operator +(MyPoint2D <T> point, MyVector2D <T> a) { MyPoint2D <T> p = point.Clone(); p.X = Arithmetics <T> .Add(p.X, a.X); p.Y = Arithmetics <T> .Add(p.Y, a.Y); return(p); } // End Operator +
} // End function Angle_Degrees public MyPoint2D <T> Schnittpunktli(MyPoint2D <T> p1, MyVector2D <T> vec1, MyPoint2D <T> p2, MyVector2D <T> vec2) { T x1 = Arithmetics <T> .Add(p1.X, vec1.X); T y1 = Arithmetics <T> .Add(p1.Y, vec1.Y); T x2 = Arithmetics <T> .Add(p2.X, vec2.X); T y2 = Arithmetics <T> .Add(p2.Y, vec2.Y); return(Schnittpunktli(p1, new MyPoint2D <T>(x1, x1), p2, new MyPoint2D <T>(x2, y2))); } // End Function Schnittpunktli
} // End Function Determinant2d public MyPoint2D <T> Schnittpunktli(MyPoint2D <T> p1, MyPoint2D <T> p2, MyPoint2D <T> p3, MyPoint2D <T> p4) { T x1 = p1.X; T x2 = p2.X; T x3 = p3.X; T x4 = p4.X; T y1 = p1.Y; T y2 = p2.Y; T y3 = p3.Y; T y4 = p4.Y; T topaX = Determinant2d(x1, y1, x2, y2); T topbX = Determinant2d(x1, Arithmetics <T> .ONE, x2, Arithmetics <T> .ONE); T topcX = Determinant2d(x3, y3, x4, y4); T topdX = Determinant2d(x3, Arithmetics <T> .ONE, x4, Arithmetics <T> .ONE); T topX = Determinant2d(topaX, topbX, topcX, topdX); T bottomaX = Determinant2d(x1, Arithmetics <T> .ONE, x2, Arithmetics <T> .ONE); T bottombX = Determinant2d(y1, Arithmetics <T> .ONE, y2, Arithmetics <T> .ONE); T bottomcX = Determinant2d(x3, Arithmetics <T> .ONE, x4, Arithmetics <T> .ONE); T bottomdX = Determinant2d(y3, Arithmetics <T> .ONE, y4, Arithmetics <T> .ONE); T bottomX = Determinant2d(bottomaX, bottombX, bottomcX, bottomdX); T x = Arithmetics <T> .Divide(topX, bottomX); T topaY = Determinant2d(x1, y1, x2, y2); T topbY = Determinant2d(y1, Arithmetics <T> .ONE, y2, Arithmetics <T> .ONE); T topcY = Determinant2d(x3, y3, x4, y4); T topdY = Determinant2d(x3, Arithmetics <T> .ONE, y4, Arithmetics <T> .ONE); T topY = Determinant2d(topaY, topbY, topcY, topdY); T bottomaY = Determinant2d(x1, Arithmetics <T> .ONE, x2, Arithmetics <T> .ONE); T bottombY = Determinant2d(y1, Arithmetics <T> .ONE, y2, Arithmetics <T> .ONE); T bottomcY = Determinant2d(x3, Arithmetics <T> .ONE, x4, Arithmetics <T> .ONE); T bottomdY = Determinant2d(y3, Arithmetics <T> .ONE, y4, Arithmetics <T> .ONE); T bottomY = Determinant2d(bottomaY, bottombY, bottomcY, bottomdY); T y = Arithmetics <T> .Divide(topY, bottomY); // m = (y2-y1)/(x2-x1) // Case 1: horizontal line: slope = 0 | y=constant, x=variable // Case 2: vertical line: slope = +/-infinity | x=constant, y=variable // Case 3: Parallel => m1 = m2 // Case 4: orthogonal resp. right-angle => m1 = -1/m2 return(new MyPoint2D <T>(x, y)); } // End Function Schnittpunktli
} // End Function ToString /// <summary> /// Returns a new Vector that is the linear blend of the 2 given Vectors /// </summary> /// <param name="a">First input vector</param> /// <param name="b">Second input vector</param> /// <param name="blend">The blend factor. a when blend=0, b when blend=1.</param> /// <returns>a when blend=0, b when blend=1, and a linear combination otherwise</returns> public static MyPoint2D <T> Lerp(MyPoint2D <T> a, MyPoint2D <T> b, T blend) { T bxax = Arithmetics <T> .Subtract(b.X, a.X); T byay = Arithmetics <T> .Subtract(b.Y, a.Y); T f1 = Arithmetics <T> .Multiply(blend, bxax); T f2 = Arithmetics <T> .Multiply(blend, byay); T x = Arithmetics <T> .Add(f1, a.X); T y = Arithmetics <T> .Add(f2, a.Y); return(new MyPoint2D <T>(x, y)); } // End Function Lerp
public MyVector2D(MyPoint2D <T> a, MyPoint2D <T> b) { this.X = Arithmetics <T> .Subtract(a.X, b.X); this.Y = Arithmetics <T> .Subtract(a.Y, b.Y); } // End Constructor
} // End Constructor public MyLine2D(MyPoint2D <T> start, MyVector2D <T> vec) { this.Start = start; this.End = start + vec; } // End Constructor
public MyLine2D(MyPoint2D <T> start, MyPoint2D <T> end) { this.Start = start; this.End = end; } // End Constructor
} // End Constructor public MyPoint2D(MyPoint2D <T> point) { this.X = point.X; this.Y = point.Y; } // End Constructor
} // End Constructor public MyVector2D(MyPoint2D <T> point) : base(point.X, point.Y) { } // End Constructor
} // End function GetPolygonCenter public uint FindNearestLineEndIndex <T>(MyPoint2D <T> cptPointToAdd) { if (this.aptDefinitionPoints.Length == 0) { return(0); } if (this.aptDefinitionPoints.Length > 1) { double nOldDistance = 1000000; uint iOldIndex = 0; double nDistance = 0; MyVector2D <T> vec2_LineStart = null; MyVector2D <T> vec2_LineEnd = null; MyVector2D <T> vec2_Point = null; MyVector2D <T> vec2_VecLine = null; MyPoint2D <T> cptIntersectionPoint = null; bool bHasFirst = false; bool bHasLast = true; uint iFirst = 0; uint iLast = 0; for (uint i = 0; i < this.aptDefinitionPoints.Length; ++i) { if (this.aptDefinitionPoints[i].bCurrentlyValid) { if (bHasFirst == false) { bHasFirst = true; iFirst = i; iLast = i; continue; } bHasLast = true; vec2_LineStart = cVector_2d.MakeVector(this.aptDefinitionPoints[iLast].x, this.aptDefinitionPoints[iLast].y); //trace("vec2_LineStart: " + vec2_LineStart.toString() ); vec2_LineEnd = cVector_2d.MakeVector(this.aptDefinitionPoints[i].x, this.aptDefinitionPoints[i].y); //trace("vec2_LineEnd: " + vec2_LineEnd.toString() ); vec2_Point = cVector_2d.MakeVector(cptPointToAdd.x, cptPointToAdd.y); //trace("vec2_Point: " + vec2_Point.toString() ); nDistance = cVector_2d.DistanceOfPointToLine(vec2_Point, vec2_LineStart, vec2_LineEnd); vec2_VecLine = cVector_2d.VectorSubtract(vec2_LineStart, vec2_LineEnd); if (nDistance < nOldDistance) { cptIntersectionPoint = cVector_2d.GetPointVerticalIntersection(this.aptDefinitionPoints[i], vec2_VecLine, cptPointToAdd); if (cptIntersectionPoint.bHasInterSection) { //trace("Has intersection"); if (cVector_2d.isPointOnLine(this.aptDefinitionPoints[i], this.aptDefinitionPoints[iLast], cptIntersectionPoint)) { //trace("is on line"); nOldDistance = nDistance; iOldIndex = i; } // else // trace("is not on line."); } // else // trace("has no intersection"); } // trace("Length: " + aptDefinitionPoints.Length); // trace("Pair["+i+"]: " + aptDefinitionPoints[iLast].toString() + " ; "+aptDefinitionPoints[i].toString() + "Distance: " + nDistance); // trace("Dist: " + nDistance ); iLast = i; } // End isvalid } // End for if (bHasLast) { // trace("Has Last..."); vec2_LineStart = cVector_2d.MakeVector(this.aptDefinitionPoints[iLast].x, this.aptDefinitionPoints[iLast].y); vec2_LineEnd = cVector_2d.MakeVector(this.aptDefinitionPoints[iFirst].x, this.aptDefinitionPoints[iFirst].y); vec2_Point = cVector_2d.MakeVector(cptPointToAdd.x, cptPointToAdd.y); nDistance = cVector_2d.DistanceOfPointToLine(vec2_Point, vec2_LineStart, vec2_LineEnd); vec2_VecLine = cVector_2d.VectorSubtract(vec2_LineStart, vec2_LineEnd); //trace("Final Pair: " + aptDefinitionPoints[iFirst].toString()+" ; " + aptDefinitionPoints[iLast].toString() + "Distance: " + nDistance); if (nDistance < nOldDistance) { // nOldDistance = nDistance; // iOldIndex = aptDefinitionPoints.Length; cptIntersectionPoint = cVector_2d.GetPointVerticalIntersection(this.aptDefinitionPoints[iLast], vec2_VecLine, cptPointToAdd); if (cptIntersectionPoint.bHasInterSection) { //trace("Is point on this line? "+ aptDefinitionPoints[iLast].toString()+", "+ aptDefinitionPoints[iFirst].toString() ); if (cVector_2d.isPointOnLine(this.aptDefinitionPoints[iLast], this.aptDefinitionPoints[iFirst], cptIntersectionPoint)) { //trace("isonline"); nOldDistance = nDistance; iOldIndex = iLast + 1; //aptDefinitionPoints.Length; } //else // trace("is not on line."); } //else // trace("has not"); } // End if(nDistance<nOldDistance) //trace("Selected pair: "+iOldIndex); return(iOldIndex); }// End if(bHasLast) else { //trace("Selected pair: 1"); return(1); } } else { return(1); } return((uint)this.aptDefinitionPoints.Length); }