using System.Windows.Media.Media3D; namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.MetroGauges.LandXMLData { public class GeometryTransformations { public GeometryTransformations() { ResetFactors(); _matrix = Matrix3D.Identity; } public const double AngleScale = 57.295779513082323; private Matrix3D _matrix; public bool IsIdentity => _matrix.IsIdentity; [Obsolete("Property \"Scale1\" is deprecated, please use \"ScaleFactor\" instead.")] public double Scale1 => ScaleFactor; public Matrix3D Matrix => _matrix; public double Phi { get; private set; } public double Theta { get; private set; } public double ScaleFactor { get; private set; } public double Dx { get; private set; } public double Dy { get; private set; } public double Dz { get; private set; } public void Invert() { ScaleFactor = 1.0 / ScaleFactor; Phi = -Phi; Theta = -Theta; Dx = -Dx; Dy = -Dy; Dz = -Dz; _matrix.Invert(); } public static bool IsPointInsidePolygon(Point2D point, IEnumerable vertices) { int num = 0; int num2 = vertices.Count(); for (int i = 0; i < num2; i++) { Point2D point2D = vertices.ElementAt(i); Point2D point2D2 = vertices.ElementAt((i + 1) % num2); if ((point.Y - point2D.Y) * (point.Y - point2D2.Y) <= 0.0) { Point2D point2D3 = point2D2 - point2D; if (point2D3.X == 0.0) { if (point2D.X == point.X) { return true; } num++; } else if (point2D.X >= point.X || point2D2.X >= point.X) { double num3 = point2D3.Y / point2D3.X; double num4 = point2D.Y - num3 * point2D.X; double num5 = -(num4 - point.Y) / num3; if (num5 == point.X) { return true; } if (point.X < num5) { num++; } } } } return num % 2 != 0; } public void Reset() { ResetFactors(); _matrix.SetIdentity(); } public void RotatePhi(double phi = 0.0) { if (phi != 0.0) { _matrix.Rotate(new Quaternion(new Vector3D(0.0, 0.0, 1.0), Phi += phi * 57.295779513082323)); } } public void RotateTheta(double theta = 0.0, Point3D point = null) { if (theta != 0.0) { if (point == null) { point = new Point3D { X = 1.0, Y = 0.0, Z = 0.0 }; } Vector3D vector = Vector3D.CrossProduct(new Vector3D(point.X, point.Y, 0.0), new Vector3D(point.X, point.Y, 1.0)); Rotation(vector, Theta += theta * 57.295779513082323); } } public void Rotation(Vector3D vector, double angle) { _matrix.Rotate(new Quaternion(vector, angle)); } public void Scale(double s = 1.0) { if (s != 1.0) { ScaleFactor *= s; _matrix.Scale(new Vector3D(s, s, s)); } } public void SetTransformations( Point3D source1, Point3D source2, Point3D destination1, Point3D destination2, double scaleDefault = 1.0, bool autoScale = true, bool resetMatrix = true ) { Point3D point3D = source2 - source1; Point3D point3D2 = destination2 - destination1; Vector3D vector = new Vector3D(point3D.X, point3D.Y, point3D.Z); Vector3D vector2 = new Vector3D(point3D2.X, point3D2.Y, point3D2.Z); double num = Vector3D.AngleBetween(vector, vector2); double num2 = scaleDefault; if (autoScale) { num2 *= vector2.Length / vector.Length; } if (resetMatrix) { Reset(); } Phi = (point3D2.Phi - point3D.Phi) * 57.295779513082323; Theta = (point3D2.Theta - point3D.Theta) * 57.295779513082323; Translation(-source1.X, -source1.Y, -source1.Z); if (num != 0.0) { Vector3D vector3 = Vector3D.CrossProduct(vector, vector2); Rotation(vector3, num); } Scale(num2); Translation(destination1.X, destination1.Y, destination1.Z); } public void SetTransformations(Point3D[] source, Point3D[] destination, double scale = 1.0, bool resetMatrix = true) { if (resetMatrix) { Reset(); } else { Phi = 0.0; Theta = 0.0; } Point3D point3D = source[0]; Point3D p = destination[0]; Translation(-point3D.X, -point3D.Y, -point3D.Z); for (int i = 1; i < Math.Min(source.Length, destination.Length); i++) { Point3D point3D2 = source[i] - point3D; Point3D point3D3 = destination[i] - p; Vector3D vector = new Vector3D(point3D2.X, point3D2.Y, point3D2.Z); Vector3D vector2 = new Vector3D(point3D3.X, point3D3.Y, point3D3.Z); double num = Vector3D.AngleBetween(vector, vector2); Phi += point3D3.Phi - point3D2.Phi; Theta += point3D3.Theta - point3D2.Theta; if (num != 0.0) { Vector3D vector3 = Vector3D.CrossProduct(vector, vector2); Rotation(vector3, num); } } Phi *= 57.295779513082323; Theta *= 57.295779513082323; Scale(scale); Translation(destination[0].X, destination[0].Y, destination[0].Z); } public void SetTransformations(Point3D point, double phi, double theta, double scale = 1.0, bool resetMatrix = true) { if (resetMatrix) { Reset(); } RotateTheta(theta, point); RotatePhi(phi); Scale(scale); } public void Transform(Point3D point) { if (!_matrix.IsIdentity) { double x = point.X; double y = point.Y; double z = point.Z; point.X = x * _matrix.M11 + y * _matrix.M21 + z * _matrix.M31 + _matrix.OffsetX; point.Y = x * _matrix.M12 + y * _matrix.M22 + z * _matrix.M32 + _matrix.OffsetY; point.Z = x * _matrix.M13 + y * _matrix.M23 + z * _matrix.M33 + _matrix.OffsetZ; if (!_matrix.IsAffine) { double num = x * _matrix.M14 + y * _matrix.M24 + z * _matrix.M34 + _matrix.M44; point.X /= num; point.Y /= num; point.Z /= num; } } } public void Translation(Point3D point = null) { if (point != null) { Translation(point.X, point.Y, point.Z); } } public void Translation(double x = 0.0, double y = 0.0, double z = 0.0) { if (x != 0.0 || y != 0.0 || z != 0.0) { Dx += x; Dy += y; Dz += z; _matrix.Translate(new Vector3D(x, y, z)); } } protected void ResetFactors() { ScaleFactor = 1.0; Phi = Theta = 0.0; Dx = Dy = Dz = 0.0; } private void Rotation(double gammaAngle, double betaAngle, double alphaAngle) { RotationX(alphaAngle); RotationY(betaAngle); RotationZ(gammaAngle); } private void RotationX(double alphaAngle) { if (alphaAngle != 0.0) { _matrix.Rotate(new Quaternion(new Vector3D(1.0, 0.0, 0.0), alphaAngle * 57.295779513082323)); } } private void RotationY(double betaAngle) { if (betaAngle != 0.0) { _matrix.Rotate(new Quaternion(new Vector3D(0.0, 1.0, 0.0), betaAngle * 57.295779513082323)); } } private void RotationZ(double gammaAngle) { if (gammaAngle != 0.0) { _matrix.Rotate(new Quaternion(new Vector3D(0.0, 0.0, 1.0), gammaAngle * 57.295779513082323)); } } private void Scale(double sx, double sy, double sz) { if (sx != 1.0 || sy != 1.0 || sz != 1.0) { ScaleFactor = double.NaN; _matrix.Scale(new Vector3D(sx, sy, sz)); } } } }