Files
Shrlalgo.RvKits/ShrlAlgoToolkit.RevitAddins/RvIndependent/MetroGauges/LandXMLData/GeometryTransformations.cs

310 lines
9.4 KiB
C#
Raw Normal View History

using System.Windows.Media.Media3D;
2025-04-24 20:56:44 +08:00
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<Point2D> 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));
}
}
}
}