private Point CalcVP(Vector a, Vector b, Vector c, Vector d) { Vector line1Cross = a.Cross(b); Vector line2Cross = c.Cross(d); Vector res = line1Cross.Cross(line2Cross); return new Point(res.X / res.Z, res.Y / res.Z); }
/// <summary> /// Returns the Inner Product also known as the dot product of two vectors, U and V /// </summary> /// <param name="u">The input vector</param> /// <param name="v">The vector to take the inner product against U</param> /// <returns>a Double containing the dot product of U and V</returns> public static double DotProduct(Vector u, Vector v) { return (u.X * v.X) + (u.Y * v.Y) + (u.Z * v.Z); }
/// <summary> /// Multiplies each component of vector U by the Scalar value /// </summary> /// <param name="u">A vector representing the vector to be multiplied</param> /// <param name="scalar">Double, the scalar value to mulitiply the vector components by</param> /// <returns>A Vector representing the vector product of vector U and the Scalar</returns> public static Vector Divide(Vector u, double scalar) { if (scalar == 0) throw new ArgumentException("Divisor cannot be 0."); return new Vector(u.X / scalar, u.Y / scalar, u.Z / scalar); }
/// <summary> /// Returns the Cross Product of two vectors U and V /// </summary> /// <param name="u">Vector, the first input vector</param> /// <param name="v">Vector, the second input vector</param> /// <returns>A Vector containing the cross product of U and V</returns> public static Vector CrossProduct(Vector u, Vector v) { Vector result = new Vector(); result.X = (u.Y * v.Z - u.Z * v.Y); result.Y = (u.Z * v.X - u.X * v.Z); result.Z = (u.X * v.Y - u.Y * v.X); return result; }
/// <summary> /// Adds the vectors U and V using vector addition, which adds the corresponding components /// </summary> /// <param name="u">One vector to be added</param> /// <param name="v">A second vector to be added</param> /// <returns></returns> public static Vector Add(Vector u, Vector v) { return new Vector(u.X + v.X, u.Y + v.Y, u.Z + v.Z); }
/// <summary> /// Override for definition of equality for vectors /// </summary> /// <param name="v">A vector to compare with</param> /// <returns>true if the X, Y, and Z coordinates are all equal</returns> public bool Equals(Vector v) { if ((X == v.X) && (Y == v.Y) && (Z == v.Z)) return true; return false; }
/// <summary> /// Returns the cross product of this vector with the specified vector V /// </summary> /// <param name="v">The vector to perform a cross product against</param> /// <returns>A vector result from the inner product</returns> public Vector Cross(Vector v) { Vector result = new Vector(); result.X = (Y * v.Z - Z * v.Y); result.Y = (Z * v.X - X * v.Z); result.Z = (X * v.Y - Y * v.X); return result; }
/// <summary> /// Subtracts Vector V from Vector U /// </summary> /// <param name="u">A Vector to subtract from</param> /// <param name="v">A Vector to subtract</param> /// <returns>The Vector difference U - V</returns> public static Vector Subtract(Vector u, Vector v) { return new Vector(u.X - v.X, u.Y - v.Y, u.Z - v.Z); }
/// <summary> /// Adds each of the elements of V to the elements of this vector /// </summary> /// <param name="v">Vector, the vector to add to this vector</param> /// <returns>A vector result from the addition</returns> public Vector Add(Vector v) { return new Vector(X + v.X, Y + v.Y, Z + v.Z); }
/// <summary> /// Subtracts each element of V from each element of this vector /// </summary> /// <param name="v">Vector, the vector to subtract from this vector</param> /// <returns>A vector result from the subtraction</returns> public Vector Subtract(Vector v) { return new Vector(X - v.X, Y - v.Y, Z - v.Z); }
/// <summary> /// Creates a new vector from a vector that can be longer or shorter than 3 ordinates. /// If an X, Y or Z value is not specified, it will become 0. Values greater than /// the Z ordinate are lost. /// </summary> /// <param name="vect"></param> public Vector(Vector vect) { X = vect.X; Y = vect.Y; Z = vect.Z; }
/// <summary> /// Calculates the shortest distance to this line segment from the specified MapWinGIS.Point /// </summary> /// <param name="point">A MapWinGIS.Point specifing the location to find the distance to the line</param> /// <returns>A double value that is the shortest distance from the given Point to this line segment</returns> public double DistanceTo(Coordinate point) { Vertex p = new Vertex(point.X, point.Y); Vertex pt = ClosestPointTo(p); Vector dist = new Vector(new Coordinate(pt.X, pt.Y), point); return dist.Length2D; }
/// <summary> /// Returns a vertex representing the closest point on this line segment from a given vertex /// </summary> /// <param name="point">The point we want to be close to</param> /// <param name="isInfiniteLine">If true treat the line as infinitly long</param> /// <param name="endPointFlag">Outputs 0 if the vertex is on the line segment, 1 if beyond P0, 2 if beyong P1 and -1 if P1=P2</param> /// <returns>The point on this segment or infinite line that is closest to the given point</returns> public Vertex ClosestPointTo(Vertex point, bool isInfiniteLine, out EndPointInteraction endPointFlag) { // If the points defining this segment are the same, we treat the segment as a point // special handling to avoid 0 in denominator later if (P2.X == P1.X && P2.Y == P1.Y) { endPointFlag = EndPointInteraction.P1equalsP2; return P1; } //http://softsurfer.com/Archive/algorithm_0102/algorithm_0102.htm Vector v = ToVector(); // vector from p1 to p2 in the segment v.Z = 0; Vector w = new Vector(P1.ToCoordinate(), point.ToCoordinate()); // vector from p1 to Point w.Z = 0; double c1 = w.Dot(v); // the dot product represents the projection onto the line if (c1 < 0) { endPointFlag = EndPointInteraction.PastP1; if (!isInfiniteLine) // The closest point on the segment to Point is p1 return P1; } double c2 = v.Dot(v); if (c2 <= c1) { endPointFlag = EndPointInteraction.PastP2; if (!isInfiniteLine) // The closest point on the segment to Point is p2 return P2; } // The closest point on the segment is perpendicular to the point, // but somewhere on the segment between P1 and P2 endPointFlag = EndPointInteraction.OnLine; double b = c1 / c2; v = v.Multiply(b); Vertex pb = new Vertex(P1.X + v.X, P1.Y + v.Y); return pb; }
/// <summary> /// Non-static version of taking the square distance for a vector /// </summary> /// <param name="u">The vector to find the square of the distance of</param> /// <returns>Double, the square of the distance</returns> public static double Norm2(Vector u) { double n2 = u.X * u.X + u.Y * u.Y + u.Z * u.Z; return n2; }
/// <summary> /// Returns the dot product of this vector with V2 /// </summary> /// <param name="v">The vector to perform an inner product against</param> /// <returns>A Double result from the inner product</returns> public double Dot(Vector v) { return X * v.X + Y * v.Y + Z * v.Z; }
/// <summary> /// Multiplies each component of vector U by the Scalar value /// </summary> /// <param name="u">A vector representing the vector to be multiplied</param> /// <param name="scalar">Double, the scalar value to mulitiply the vector components by</param> /// <returns>A Vector representing the vector product of vector U and the Scalar</returns> public static Vector Multiply(Vector u, double scalar) { return new Vector(u.X * scalar, u.Y * scalar, u.Z * scalar); }
/// <summary> /// Compares the values of each element, and if all the elements are equal, returns true. /// </summary> /// <param name="v">The vector to compare against this vector.</param> /// <returns>Boolean, true if all the elements have the same value.</returns> public bool Intersects(Vector v) { if ((X == v.X) && (Y == v.Y) && (Z == v.Z)) return true; return false; }
/// <summary> /// Returns the Cross Product of two vectors U and V /// </summary> /// <param name="u">Vector, the first input vector</param> /// <param name="v">Vector, the second input vector</param> /// <returns>A Vector containing the cross product of U and V</returns> public static Vector operator ^(Vector u, Vector v) { Vector result = new Vector(); result.X = (u.Y * v.Z - u.Z * v.Y); result.Y = (u.Z * v.X - u.X * v.Z); result.Z = (u.X * v.Y - u.Y * v.X); return result; }
/// <summary> /// Returns the intersection of the specified segment with this bounding box. If there is no intersection, /// then this returns null. If the intersection is a corner, then the LineSegment will be degenerate, /// that is both the coordinates will be the same. Otherwise, the segment will be returned so that the /// direction is the same as the original segment. /// </summary> /// <param name="self">The IEnvelope to use with this method</param> /// <param name="segment">The LineSegment to intersect.</param> /// <returns>An ILineSegment that is cropped to fit within the bounding box.</returns> public static ILineSegment Intersection(this IEnvelope self, ILineSegment segment) { if (self == null) return null; if (self.IsNull) return null; if (segment == null) return null; // If the line segment is completely contained by this envelope, simply return the original. if (self.Contains(segment.P0) && self.Contains(segment.P1)) return segment; int count = 0; Coordinate[] borderPoints = new Coordinate[2]; ILineSegment[] border = self.BorderSegments(); for (int i = 0; i < 4; i++) { borderPoints[count] = border[i].Intersection(segment); if (borderPoints[count] != null) { count++; if (count > 1) break; } } // If there are two intersections, the line crosses this envelope if (count == 2) { Vector v = new Vector(segment.P0, segment.P1); Vector t = new Vector(borderPoints[0], borderPoints[1]); return t.Dot(v) < 0 ? new LineSegment(borderPoints[1], borderPoints[0]) : new LineSegment(borderPoints[0], borderPoints[1]); } // if there is only one intersection, we probably have one point contained and one point not-contained if (count == 1) { if (self.Contains(segment.P0)) { // P1 got cropped, so make a line from p0 to the cropped point return new LineSegment(segment.P0, borderPoints[0]); } return self.Contains(segment.P1) ? new LineSegment(borderPoints[0], segment.P1) : new LineSegment(borderPoints[0], borderPoints[0]); } return null; }