|
@@ -0,0 +1,907 @@
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Runtime.InteropServices;
|
|
|
+using SAGA.DotNetUtils.Extend;
|
|
|
+
|
|
|
+namespace SAGA.DotNetUtils.Geometry
|
|
|
+{
|
|
|
+ public class TszXYZ
|
|
|
+ {
|
|
|
+ internal xyz mxyz;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a TszXYZ object (0.0,0.0,0.0).
|
|
|
+ /// </summary>
|
|
|
+ public TszXYZ()
|
|
|
+ {
|
|
|
+ this.x = 0.0;
|
|
|
+ this.y = 0.0;
|
|
|
+ this.z = 0.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TszXYZ(double X, double Y)
|
|
|
+ {
|
|
|
+ this.x = X;
|
|
|
+ this.y = Y;
|
|
|
+ this.z = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TszXYZ(TszXYZ pt, double Z)
|
|
|
+ {
|
|
|
+ this.x = pt.x;
|
|
|
+ this.y = pt.y;
|
|
|
+ this.z = Z;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a TszXYZ object (X,Y,Z).
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="X">The x coordinate of the point.</param>
|
|
|
+ /// <param name="Y">The y coordinate of the point.</param>
|
|
|
+ /// <param name="Z">The z coordinate of the point.</param>
|
|
|
+ public TszXYZ(double X, double Y, double Z)
|
|
|
+ {
|
|
|
+ this.x = X;
|
|
|
+ this.y = Y;
|
|
|
+ this.z = Z;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a TszXYZ object at the coordinates of the pt parameter.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="pt">A TszXYZ object from which the coordinjates will be taken from.</param>
|
|
|
+ public TszXYZ(TszXYZ pt)
|
|
|
+ {
|
|
|
+ this.x = pt.x;
|
|
|
+ this.y = pt.y;
|
|
|
+ this.z = pt.z;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// The x value of the point.
|
|
|
+ /// </summary>
|
|
|
+ public double x
|
|
|
+ {
|
|
|
+ get { return this.mxyz._x; }
|
|
|
+ set { this.mxyz._x = value; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// The y value of the point.
|
|
|
+ /// </summary>
|
|
|
+ public double y
|
|
|
+ {
|
|
|
+ get { return this.mxyz._y; }
|
|
|
+ set { this.mxyz._y = value; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// The z value of the point.
|
|
|
+ /// </summary>
|
|
|
+ public double z
|
|
|
+ {
|
|
|
+ get { return this.mxyz._z; }
|
|
|
+ set { this.mxyz._z = value; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// X
|
|
|
+ /// </summary>
|
|
|
+ public static TszXYZ BasisX
|
|
|
+ {
|
|
|
+ get { return new TszXYZ(1, 0, 0); }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Y
|
|
|
+ /// </summary>
|
|
|
+ public static TszXYZ BasisY
|
|
|
+ {
|
|
|
+ get { return new TszXYZ(0, 1, 0); }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Z
|
|
|
+ /// </summary>
|
|
|
+ public static TszXYZ BasisZ
|
|
|
+ {
|
|
|
+ get { return new TszXYZ(0, 0, 1); }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Get the angle between the given point and this in radians.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="pt">The other gPoint needed.</param>
|
|
|
+ /// <returns>The angle in radians.</returns>
|
|
|
+ public double GetAngle(TszXYZ pt)
|
|
|
+ {
|
|
|
+ return TszGeoUtil.GetAngle(this, pt);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the + operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="pt"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszXYZ operator +(TszXYZ p, TszXYZ pt)
|
|
|
+ {
|
|
|
+ TszXYZ point = new TszXYZ();
|
|
|
+ point.x = p.x + pt.x;
|
|
|
+ point.y = p.y + pt.y;
|
|
|
+ point.z = p.z + pt.z;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the / operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszXYZ operator /(TszXYZ p, double value)
|
|
|
+ {
|
|
|
+ TszXYZ point = new TszXYZ();
|
|
|
+ point.x = p.x/value;
|
|
|
+ point.y = p.y/value;
|
|
|
+ point.z = p.z/value;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the == operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="a"></param>
|
|
|
+ /// <param name="b"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static bool operator ==(TszXYZ a, TszXYZ b)
|
|
|
+ {
|
|
|
+ return (ReferenceEquals(a, b) || (((null != a) && (null != b)) && a.Equals(b)));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the != operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="obj1"></param>
|
|
|
+ /// <param name="obj2"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static bool operator !=(TszXYZ obj1, TszXYZ obj2)
|
|
|
+ {
|
|
|
+ return !(obj1 == obj2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the * operator for a TszXYZ with a double value.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszXYZ operator *(double value, TszXYZ p)
|
|
|
+ {
|
|
|
+ TszXYZ point = new TszXYZ();
|
|
|
+ point.x = p.x*value;
|
|
|
+ point.y = p.y*value;
|
|
|
+ point.z = p.z*value;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the * operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszXYZ operator *(TszXYZ p, double value)
|
|
|
+ {
|
|
|
+ TszXYZ point = new TszXYZ();
|
|
|
+ point.x = p.x*value;
|
|
|
+ point.y = p.y*value;
|
|
|
+ point.z = p.z*value;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the - operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="pt"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszXYZ operator -(TszXYZ p, TszXYZ pt)
|
|
|
+ {
|
|
|
+ TszXYZ point = new TszXYZ();
|
|
|
+ point.x = p.x - pt.x;
|
|
|
+ point.y = p.y - pt.y;
|
|
|
+ point.z = p.z - pt.z;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Serves as a hash function for the collection.
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public override int GetHashCode()
|
|
|
+ {
|
|
|
+ return ((this.x.GetHashCode() ^ this.y.GetHashCode()) ^ this.z.GetHashCode());
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Checks if the parameter object is equal to this object.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="obj">An object to be checked if it is equal with this TszXYZ object.</param>
|
|
|
+ /// <returns>True if the objects are equal.</returns>
|
|
|
+ public override bool Equals(object obj)
|
|
|
+ {
|
|
|
+ if (obj == null)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ TszXYZ p = obj as TszXYZ;
|
|
|
+ return this.Equals(p);
|
|
|
+ }
|
|
|
+
|
|
|
+ public override string ToString()
|
|
|
+ {
|
|
|
+ return string.Format("({0},{1},{2})", this.x, this.y, this.z);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 相等判断
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="dTol"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public bool Equals(TszXYZ p, double dTol = 0)
|
|
|
+ {
|
|
|
+ if (p == null)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return (((this.x.IsEqual(p.x, dTol)) && (this.y.IsEqual(p.y, dTol))) && (this.z.IsEqual(p.z, dTol)));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Convert this Vector to one unit length.
|
|
|
+ /// </summary>
|
|
|
+ public TszXYZ Normalize()
|
|
|
+ {
|
|
|
+ double dX = 0;
|
|
|
+ double dY = 0;
|
|
|
+ double dZ = 0;
|
|
|
+ double num = Math.Sqrt(((x*x) + (y*y)) + (z*z));
|
|
|
+ if (TszGeoUtil.AreEqual(num, 0.0, 1E-08))
|
|
|
+ {
|
|
|
+ dX = 0.0;
|
|
|
+ dY = 0.0;
|
|
|
+ dZ = 1.0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dX = x/num;
|
|
|
+ dY = y/num;
|
|
|
+ dZ = z/num;
|
|
|
+ if (TszGeoUtil.AreEqual(dX, 0.0, 1E-08))
|
|
|
+ {
|
|
|
+ dX = 0.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dX, 1.0, 1E-08))
|
|
|
+ {
|
|
|
+ dX = 1.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dY, 0.0, 1E-08))
|
|
|
+ {
|
|
|
+ dY = 0.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dY, 1.0, 1E-08))
|
|
|
+ {
|
|
|
+ dY = 1.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dZ, 0.0, 1E-08))
|
|
|
+ {
|
|
|
+ dZ = 0.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dZ, 1.0, 1E-08))
|
|
|
+ {
|
|
|
+ dZ = 1.0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new TszXYZ(dX, dY, dZ);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Changes this Vector regarding the crossing operation with another Vector.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="other">A Vector object required for the operation.</param>
|
|
|
+ public void Cross(TszXYZ other)
|
|
|
+ {
|
|
|
+ double num = (y*other.z) - (other.y*z);
|
|
|
+ double num2 = (z*other.x) - (other.z*x);
|
|
|
+ double num3 = (x*other.y) - (other.x*y);
|
|
|
+ x = num;
|
|
|
+ y = num2;
|
|
|
+ z = num3;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculates and returns a Vector produced by crossing two other Vectors.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="v1">First Vector used.</param>
|
|
|
+ /// <param name="v2">Second Vector used.</param>
|
|
|
+ /// <returns>A Vector as a crossing result from the passed two vectors.</returns>
|
|
|
+ public static TszXYZ CrossProduct(TszXYZ v1, TszXYZ v2)
|
|
|
+ {
|
|
|
+ TszXYZ vector = new TszXYZ(v1);
|
|
|
+ vector.Cross(v2);
|
|
|
+ return vector;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Check if the passed TszXYZ has equal x,y,z values with this object.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="pt">A TszXYZ to be checked if it is equal to this object.</param>
|
|
|
+ /// <param name="Equality">A double value representing the equality(for example 0.00001).</param>
|
|
|
+ /// <returns>True if the x,y,z values are equal.</returns>
|
|
|
+ public bool AreEqual(TszXYZ pt, double Equality)
|
|
|
+ {
|
|
|
+ return ((((pt != null) && TszGeoUtil.AreEqual(this.x, pt.x, Equality)) &&
|
|
|
+ TszGeoUtil.AreEqual(this.y, pt.y, Equality)) && TszGeoUtil.AreEqual(this.z, pt.z, Equality));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Returns the distance between this TszXYZ and the parameter.The z is not taken into consideration.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="pt">A TszXYZ needed for the calculation of the distance.</param>
|
|
|
+ /// <returns>The 2D distance between the two points.</returns>
|
|
|
+ public virtual double FindDistance2(TszXYZ pt)
|
|
|
+ {
|
|
|
+ return Math.Sqrt(((this.x - pt.x)*(this.x - pt.x)) + ((this.y - pt.y)*(this.y - pt.y)));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculates the 2D distance between two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fromThis">First TszXYZ needed.</param>
|
|
|
+ /// <param name="toThis">Second TszXYZ needed.</param>
|
|
|
+ /// <returns>The 2D distance between the two given gPoints.</returns>
|
|
|
+ public static double FindDistance2(TszXYZ fromThis, TszXYZ toThis)
|
|
|
+ {
|
|
|
+ return
|
|
|
+ Math.Sqrt(((fromThis.x - toThis.x)*(fromThis.x - toThis.x)) +
|
|
|
+ ((fromThis.y - toThis.y)*(fromThis.y - toThis.y)));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Returns the distance between this TszXYZ and the parameter.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="other">A TszXYZ needed for the calculation of the distance.</param>
|
|
|
+ /// <returns>The distance between the two points.</returns>
|
|
|
+ public virtual double Distance3D(TszXYZ other)
|
|
|
+ {
|
|
|
+ return Math.Sqrt(this.DistanceSquared(other));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculates the distance between two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fromThis">First TszXYZ needed.</param>
|
|
|
+ /// <param name="toThis">Second TszXYZ needed.</param>
|
|
|
+ /// <returns>The distance between the two given gPoints.</returns>
|
|
|
+ public static double Distance3D(TszXYZ fromThis, TszXYZ toThis)
|
|
|
+ {
|
|
|
+ return Math.Sqrt(DistanceSquared(fromThis, toThis));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Returns the square of the distance between two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="other">The other TszXYZ object.</param>
|
|
|
+ /// <returns>The square of distance between the given TszXYZ and this one.</returns>
|
|
|
+ public virtual double DistanceSquared(TszXYZ other)
|
|
|
+ {
|
|
|
+ double num = other.x - this.x;
|
|
|
+ double num2 = other.y - this.y;
|
|
|
+ double num3 = other.z - this.z;
|
|
|
+ return (((num*num) + (num2*num2)) + (num3*num3));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculate the squared distance between two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fromThis">First TszXYZ needed.</param>
|
|
|
+ /// <param name="toThis">Second TszXYZ needed</param>
|
|
|
+ /// <returns>The squared distance between the two given gPoints.</returns>
|
|
|
+ public static double DistanceSquared(TszXYZ fromThis, TszXYZ toThis)
|
|
|
+ {
|
|
|
+ double num = toThis.x - fromThis.x;
|
|
|
+ double num2 = toThis.y - fromThis.y;
|
|
|
+ double num3 = toThis.z - fromThis.z;
|
|
|
+ return (((num*num) + (num2*num2)) + (num3*num3));
|
|
|
+ }
|
|
|
+
|
|
|
+ public TszXYZ Round()
|
|
|
+ {
|
|
|
+ return new TszXYZ(x.Round(), y.Round(), z.Round());
|
|
|
+ }
|
|
|
+
|
|
|
+ public TszXYZ NewZ(double dZ)
|
|
|
+ {
|
|
|
+ return new TszXYZ(x, y, dZ);
|
|
|
+ }
|
|
|
+
|
|
|
+ [StructLayout(LayoutKind.Sequential)]
|
|
|
+ internal struct xyz
|
|
|
+ {
|
|
|
+ internal double _x;
|
|
|
+ internal double _y;
|
|
|
+ internal double _z;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class TszXYZComparer : IComparer<TszXYZ>
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 左下、右上
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="first"></param>
|
|
|
+ /// <param name="second"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ int IComparer<TszXYZ>.Compare(TszXYZ first, TszXYZ second)
|
|
|
+ {
|
|
|
+ // first compare z coordinate, then y coordinate, at last x coordinate
|
|
|
+ if (TszGeoUtil.IsEqual(first.z, second.z))
|
|
|
+ {
|
|
|
+ if (TszGeoUtil.IsEqual(first.y, second.y))
|
|
|
+ {
|
|
|
+ if (TszGeoUtil.IsEqual(first.x, second.x))
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return (first.x > second.x) ? 1 : -1;
|
|
|
+ }
|
|
|
+ return (first.y > second.y) ? 1 : -1;
|
|
|
+ }
|
|
|
+ return (first.z > second.z) ? 1 : -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class TszVector
|
|
|
+ {
|
|
|
+ internal xyz mxyz;
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a TszVector object (0.0,0.0,0.0).
|
|
|
+ /// </summary>
|
|
|
+ public TszVector()
|
|
|
+ {
|
|
|
+ this.x = 0.0;
|
|
|
+ this.y = 0.0;
|
|
|
+ this.z = 0.0;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TszVector(double X, double Y)
|
|
|
+ {
|
|
|
+ this.x = X;
|
|
|
+ this.y = Y;
|
|
|
+ this.z = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ public TszVector(TszVector pt, double Z)
|
|
|
+ {
|
|
|
+ this.x = pt.x;
|
|
|
+ this.y = pt.y;
|
|
|
+ this.z = Z;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a TszVector object (X,Y,Z).
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="X">The x coordinate of the point.</param>
|
|
|
+ /// <param name="Y">The y coordinate of the point.</param>
|
|
|
+ /// <param name="Z">The z coordinate of the point.</param>
|
|
|
+ public TszVector(double X, double Y, double Z)
|
|
|
+ {
|
|
|
+ this.x = X;
|
|
|
+ this.y = Y;
|
|
|
+ this.z = Z;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Initializes a TszVector object at the coordinates of the pt parameter.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="pt">A TszVector object from which the coordinjates will be taken from.</param>
|
|
|
+ public TszVector(TszVector pt)
|
|
|
+ {
|
|
|
+ this.x = pt.x;
|
|
|
+ this.y = pt.y;
|
|
|
+ this.z = pt.z;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// The x value of the point.
|
|
|
+ /// </summary>
|
|
|
+ public double x
|
|
|
+ {
|
|
|
+ get { return this.mxyz._x; }
|
|
|
+ set { this.mxyz._x = value; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// The y value of the point.
|
|
|
+ /// </summary>
|
|
|
+ public double y
|
|
|
+ {
|
|
|
+ get { return this.mxyz._y; }
|
|
|
+ set { this.mxyz._y = value; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// The z value of the point.
|
|
|
+ /// </summary>
|
|
|
+ public double z
|
|
|
+ {
|
|
|
+ get { return this.mxyz._z; }
|
|
|
+ set { this.mxyz._z = value; }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// X
|
|
|
+ /// </summary>
|
|
|
+ public static TszVector BasisX
|
|
|
+ {
|
|
|
+ get { return new TszVector(1, 0, 0); }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Y
|
|
|
+ /// </summary>
|
|
|
+ public static TszVector BasisY
|
|
|
+ {
|
|
|
+ get { return new TszVector(0, 1, 0); }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Z
|
|
|
+ /// </summary>
|
|
|
+ public static TszVector BasisZ
|
|
|
+ {
|
|
|
+ get { return new TszVector(0, 0, 1); }
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the + operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="pt"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszVector operator +(TszVector p, TszVector pt)
|
|
|
+ {
|
|
|
+ TszVector point = new TszVector();
|
|
|
+ point.x = p.x + pt.x;
|
|
|
+ point.y = p.y + pt.y;
|
|
|
+ point.z = p.z + pt.z;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the / operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszVector operator /(TszVector p, double value)
|
|
|
+ {
|
|
|
+ TszVector point = new TszVector();
|
|
|
+ point.x = p.x/value;
|
|
|
+ point.y = p.y/value;
|
|
|
+ point.z = p.z/value;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the == operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="a"></param>
|
|
|
+ /// <param name="b"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static bool operator ==(TszVector a, TszVector b)
|
|
|
+ {
|
|
|
+ return (ReferenceEquals(a, b) || (((null != a) && (null != b)) && a.Equals(b)));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the != operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="obj1"></param>
|
|
|
+ /// <param name="obj2"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static bool operator !=(TszVector obj1, TszVector obj2)
|
|
|
+ {
|
|
|
+ return !(obj1 == obj2);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the * operator for a TszVector with a double value.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszVector operator *(double value, TszVector p)
|
|
|
+ {
|
|
|
+ TszVector point = new TszVector();
|
|
|
+ point.x = p.x*value;
|
|
|
+ point.y = p.y*value;
|
|
|
+ point.z = p.z*value;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the * operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="value"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszVector operator *(TszVector p, double value)
|
|
|
+ {
|
|
|
+ TszVector point = new TszVector();
|
|
|
+ point.x = p.x*value;
|
|
|
+ point.y = p.y*value;
|
|
|
+ point.z = p.z*value;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Implements the - operator for two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p"></param>
|
|
|
+ /// <param name="pt"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static TszVector operator -(TszVector p, TszVector pt)
|
|
|
+ {
|
|
|
+ TszVector point = new TszVector();
|
|
|
+ point.x = p.x - pt.x;
|
|
|
+ point.y = p.y - pt.y;
|
|
|
+ point.z = p.z - pt.z;
|
|
|
+ return point;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Serves as a hash function for the collection.
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public override int GetHashCode()
|
|
|
+ {
|
|
|
+ return ((this.x.GetHashCode() ^ this.y.GetHashCode()) ^ this.z.GetHashCode());
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Checks if the parameter object is equal to this object.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="obj">An object to be checked if it is equal with this TszVector object.</param>
|
|
|
+ /// <returns>True if the objects are equal.</returns>
|
|
|
+ public override bool Equals(object obj)
|
|
|
+ {
|
|
|
+ if (obj == null)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ TszVector p = obj as TszVector;
|
|
|
+ return this.Equals(p);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Checks if the parameter TszVector object is equal to this object.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="p">A TszVector object to be checked if the x,y,z values are the same with this object's values.</param>
|
|
|
+ /// <returns>True if all x,y,z values are equal.</returns>
|
|
|
+ public bool Equals(TszVector p)
|
|
|
+ {
|
|
|
+ if (p == null)
|
|
|
+ {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return (((this.x == p.x) && (this.y == p.y)) && (this.z == p.z));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Convert this Vector to one unit length.
|
|
|
+ /// </summary>
|
|
|
+ public TszVector Normalize()
|
|
|
+ {
|
|
|
+ double dX = 0;
|
|
|
+ double dY = 0;
|
|
|
+ double dZ = 0;
|
|
|
+ double num = Math.Sqrt(((x*x) + (y*y)) + (z*z));
|
|
|
+ if (TszGeoUtil.AreEqual(num, 0.0, 1E-08))
|
|
|
+ {
|
|
|
+ dX = 0.0;
|
|
|
+ dY = 0.0;
|
|
|
+ dZ = 1.0;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ dX = x/num;
|
|
|
+ dY = y/num;
|
|
|
+ dZ = z/num;
|
|
|
+ if (TszGeoUtil.AreEqual(dX, 0.0, 1E-08))
|
|
|
+ {
|
|
|
+ dX = 0.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dX, 1.0, 1E-08))
|
|
|
+ {
|
|
|
+ dX = 1.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dY, 0.0, 1E-08))
|
|
|
+ {
|
|
|
+ dY = 0.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dY, 1.0, 1E-08))
|
|
|
+ {
|
|
|
+ dY = 1.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dZ, 0.0, 1E-08))
|
|
|
+ {
|
|
|
+ dZ = 0.0;
|
|
|
+ }
|
|
|
+ if (TszGeoUtil.AreEqual(dZ, 1.0, 1E-08))
|
|
|
+ {
|
|
|
+ dZ = 1.0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return new TszVector(dX, dY, dZ);
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Changes this Vector regarding the crossing operation with another Vector.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="other">A Vector object required for the operation.</param>
|
|
|
+ public void Cross(TszVector other)
|
|
|
+ {
|
|
|
+ double num = (y*other.z) - (other.y*z);
|
|
|
+ double num2 = (z*other.x) - (other.z*x);
|
|
|
+ double num3 = (x*other.y) - (other.x*y);
|
|
|
+ x = num;
|
|
|
+ y = num2;
|
|
|
+ z = num3;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculates and returns a Vector produced by crossing two other Vectors.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="v1">First Vector used.</param>
|
|
|
+ /// <param name="v2">Second Vector used.</param>
|
|
|
+ /// <returns>A Vector as a crossing result from the passed two vectors.</returns>
|
|
|
+ public static TszVector CrossProduct(TszVector v1, TszVector v2)
|
|
|
+ {
|
|
|
+ TszVector vector = new TszVector(v1);
|
|
|
+ vector.Cross(v2);
|
|
|
+ return vector;
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Check if the passed TszVector has equal x,y,z values with this object.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="pt">A TszVector to be checked if it is equal to this object.</param>
|
|
|
+ /// <param name="Equality">A double value representing the equality(for example 0.00001).</param>
|
|
|
+ /// <returns>True if the x,y,z values are equal.</returns>
|
|
|
+ public bool AreEqual(TszVector pt, double Equality)
|
|
|
+ {
|
|
|
+ return ((((pt != null) && TszGeoUtil.AreEqual(this.x, pt.x, Equality)) &&
|
|
|
+ TszGeoUtil.AreEqual(this.y, pt.y, Equality)) && TszGeoUtil.AreEqual(this.z, pt.z, Equality));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Returns the distance between this TszVector and the parameter.The z is not taken into consideration.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="pt">A TszVector needed for the calculation of the distance.</param>
|
|
|
+ /// <returns>The 2D distance between the two points.</returns>
|
|
|
+ public virtual double FindDistance2(TszVector pt)
|
|
|
+ {
|
|
|
+ return Math.Sqrt(((this.x - pt.x)*(this.x - pt.x)) + ((this.y - pt.y)*(this.y - pt.y)));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculates the 2D distance between two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fromThis">First TszVector needed.</param>
|
|
|
+ /// <param name="toThis">Second TszVector needed.</param>
|
|
|
+ /// <returns>The 2D distance between the two given gPoints.</returns>
|
|
|
+ public static double FindDistance2(TszVector fromThis, TszVector toThis)
|
|
|
+ {
|
|
|
+ return
|
|
|
+ Math.Sqrt(((fromThis.x - toThis.x)*(fromThis.x - toThis.x)) +
|
|
|
+ ((fromThis.y - toThis.y)*(fromThis.y - toThis.y)));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Returns the distance between this TszVector and the parameter.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="other">A TszVector needed for the calculation of the distance.</param>
|
|
|
+ /// <returns>The distance between the two points.</returns>
|
|
|
+ public virtual double Distance3D(TszVector other)
|
|
|
+ {
|
|
|
+ return Math.Sqrt(this.DistanceSquared(other));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculates the distance between two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fromThis">First TszVector needed.</param>
|
|
|
+ /// <param name="toThis">Second TszVector needed.</param>
|
|
|
+ /// <returns>The distance between the two given gPoints.</returns>
|
|
|
+ public static double Distance3D(TszVector fromThis, TszVector toThis)
|
|
|
+ {
|
|
|
+ return Math.Sqrt(DistanceSquared(fromThis, toThis));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Returns the square of the distance between two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="other">The other TszVector object.</param>
|
|
|
+ /// <returns>The square of distance between the given TszVector and this one.</returns>
|
|
|
+ public virtual double DistanceSquared(TszVector other)
|
|
|
+ {
|
|
|
+ double num = other.x - this.x;
|
|
|
+ double num2 = other.y - this.y;
|
|
|
+ double num3 = other.z - this.z;
|
|
|
+ return (((num*num) + (num2*num2)) + (num3*num3));
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// Calculate the squared distance between two gPoints.
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fromThis">First TszVector needed.</param>
|
|
|
+ /// <param name="toThis">Second TszVector needed</param>
|
|
|
+ /// <returns>The squared distance between the two given gPoints.</returns>
|
|
|
+ public static double DistanceSquared(TszVector fromThis, TszVector toThis)
|
|
|
+ {
|
|
|
+ double num = toThis.x - fromThis.x;
|
|
|
+ double num2 = toThis.y - fromThis.y;
|
|
|
+ double num3 = toThis.z - fromThis.z;
|
|
|
+ return (((num*num) + (num2*num2)) + (num3*num3));
|
|
|
+ }
|
|
|
+
|
|
|
+ public TszVector Round()
|
|
|
+ {
|
|
|
+ return new TszVector(x.Round(), y.Round(), z.Round());
|
|
|
+ }
|
|
|
+
|
|
|
+ public TszVector NewZ(double dZ)
|
|
|
+ {
|
|
|
+ return new TszVector(x, y, dZ);
|
|
|
+ }
|
|
|
+
|
|
|
+ [StructLayout(LayoutKind.Sequential)]
|
|
|
+ internal struct xyz
|
|
|
+ {
|
|
|
+ internal double _x;
|
|
|
+ internal double _y;
|
|
|
+ internal double _z;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public class VectorComparer : IComparer<TszVector>
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 左下、右上
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="first"></param>
|
|
|
+ /// <param name="second"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ int IComparer<TszVector>.Compare(TszVector first, TszVector second)
|
|
|
+ {
|
|
|
+ // first compare z coordinate, then y coordinate, at last x coordinate
|
|
|
+ if (TszGeoUtil.IsEqual(first.z, second.z))
|
|
|
+ {
|
|
|
+ if (TszGeoUtil.IsEqual(first.y, second.y))
|
|
|
+ {
|
|
|
+ if (TszGeoUtil.IsEqual(first.x, second.x))
|
|
|
+ {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ return (first.x > second.x) ? 1 : -1;
|
|
|
+ }
|
|
|
+ return (first.y > second.y) ? 1 : -1;
|
|
|
+ }
|
|
|
+ return (first.z > second.z) ? 1 : -1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|