2025-02-10 20:53:40 +08:00
|
|
|
|
using System.Windows.Media.Media3D;
|
|
|
|
|
|
|
2025-04-24 20:56:44 +08:00
|
|
|
|
namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.MetroGauges.LandXMLData
|
2025-02-10 20:53:40 +08:00
|
|
|
|
{
|
|
|
|
|
|
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));
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|