using System.Xml.Serialization; namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.MetroGauges.LandXMLData { [XmlType("Point3D")] [Serializable] public class Point3D : Point2D { public Point3D() { Z = 0.0; } public Point3D(Point3D source) : base(source) { Z = source.Z; } public Point3D(double x, double y = 0.0, double z = 0.0) : base(x, y) { Z = z; } public Point3D(Point3D source, double dx, double dy = 0.0, double dz = 0.0) : base(source, dx, dy) { Z = source.Z + dz; } [XmlIgnore] public double Alpha => ( Z != 0.0 ? Y != 0.0 ? Math.Asin(Z / Math.Sqrt(Y * Y + Z * Z)) : Math.Sign(Z) * 3.1415926535897931 * 0.5 : 0.0 ) + (Y < 0.0 ? 3.1415926535897931 : 0.0); [XmlIgnore] public double Beta => ( X != 0.0 ? Z != 0.0 ? Math.Asin(X / Math.Sqrt(X * X + Z * Z)) : Math.Sign(X) * 3.1415926535897931 * 0.5 : 0.0 ) + (Z < 0.0 ? 3.1415926535897931 : 0.0); [XmlIgnore] public double Length3D => Math.Sqrt(LengthSquared3D); [XmlIgnore] public override double LengthSquared => LengthSquared3D; [XmlIgnore] public double LengthSquared3D => LengthSquared2D + Z * Z; [XmlIgnore] public double Phi => Gamma; [XmlIgnore] public double SinPhi => SinGamma; [XmlIgnore] public double SinTheta { get { if (Z == 0.0) { return 0.0; } return Z / Length3D; } } [XmlIgnore] public double Theta => Math.Asin(SinTheta); [XmlAttribute("z")] public double Z { get; set; } public override bool Equals(object obj) { return Equals(obj as Point3D); } public bool Equals(Point3D p3d) { return !ReferenceEquals(p3d, null) && ValuesEqual(this, p3d); } public override int GetHashCode() { return base.GetHashCode(); } public static Point3D operator +(Point3D p1, Point3D p2) { if (p1 != null) { if (p2 != null) { return new Point3D { X = p1.X + p2.X, Y = p1.Y + p2.Y, Z = p1.Z + p2.Z }; } return p1; } if (p2 != null) { return p2; } return null; } public static Point3D operator /(Point3D p1, double f) { if (p1 == null) { return null; } if (f != 0.0) { return new Point3D { X = p1.X / f, Y = p1.Y / f, Z = p1.Z / f }; } throw new ArgumentException(); } public static bool operator ==(Point3D p1, Point3D p2) { return ReferenceEquals(p1, p2) || (!ReferenceEquals(p1, null) && !ReferenceEquals(p2, null) && ValuesEqual(p1, p2)); } public static Point3D operator ^(Point3D p1, Point3D p2) { if (p1 == null) { return new Point3D(); } if (p2 != null) { return new Point3D { X = p1.Y * p2.Z - p2.Y * p1.Z, Y = p1.X * p2.Z - p2.X * p1.Z, Z = p1.X * p2.Y - p1.Y * p2.X }; } return new Point3D(); } public static bool operator !=(Point3D p1, Point3D p2) { return !ReferenceEquals(p1, p2) && (ReferenceEquals(p1, null) || ReferenceEquals(p2, null) || !ValuesEqual(p1, p2)); } public static double operator *(Point3D p1, Point3D p2) { if (p1 == null) { return 0.0; } if (p2 != null) { return p1.X * p2.X + p1.Y * p2.Y + p1.Z * p2.Z; } return 0.0; } public static Point3D operator *(Point3D p1, double f) { if (p1 == null) { return null; } if (f != 0.0) { return new Point3D { X = p1.X * f, Y = p1.Y * f, Z = p1.Z * f }; } return new Point3D(); } public static Point3D operator -(Point3D p1, Point3D p2) { if (p1 != null) { if (p2 != null) { return new Point3D { X = p1.X - p2.X, Y = p1.Y - p2.Y, Z = p1.Z - p2.Z }; } return p1; } if (p2 != null) { return new Point3D { X = -p2.X, Y = -p2.Y, Z = -p2.Z }; } return null; } public static Point3D operator -(Point3D p1) { if (p1 != null) { return new Point3D { X = -p1.X, Y = -p1.Y, Z = -p1.Z }; } return null; } public static bool ValuesEqual(Point3D p1, Point3D p2) { double num = (Math.Abs(p1.Z) > Math.Abs(p2.Z) ? Math.Abs(p1.Z) : Math.Abs(p2.Z)) * precision; return Math.Abs(p1.Z - p2.Z) <= num && Point2D.ValuesEqual(p1, p2); } } }