Добавьте файлы проекта.
This commit is contained in:
31
Geometry/BoundingBox2d.cs
Normal file
31
Geometry/BoundingBox2d.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class BoundingBox2d
|
||||
{
|
||||
Point2d min;
|
||||
Point2d max;
|
||||
|
||||
public Point2d Min { get => min; private set => min = value; }
|
||||
public Point2d Max { get => max; private set => max = value; }
|
||||
|
||||
public BoundingBox2d()
|
||||
{
|
||||
min = new Point2d();
|
||||
max = new Point2d();
|
||||
}
|
||||
|
||||
public BoundingBox2d(Point2d minPt, Point2d maxPt)
|
||||
{
|
||||
min = minPt;
|
||||
max = maxPt;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
9
Geometry/IVector.cs
Normal file
9
Geometry/IVector.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Geo
|
||||
{
|
||||
public interface IVector
|
||||
{
|
||||
int N { get; }
|
||||
|
||||
double[] ToArray();
|
||||
}
|
||||
}
|
||||
96
Geometry/Line2d.cs
Normal file
96
Geometry/Line2d.cs
Normal file
@@ -0,0 +1,96 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Line2d
|
||||
{
|
||||
protected Point3d startPoint;
|
||||
protected Point3d endPoint;
|
||||
protected Vector2d directive;
|
||||
protected Vector2d normal;
|
||||
|
||||
public Point3d StartPoint { get => startPoint; set { startPoint = value; if (EndPoint != null) { directive = endPoint.ToPoint2d() - startPoint.ToPoint2d(); CalcLine(); }; } }
|
||||
public Point3d EndPoint { get => endPoint; set { endPoint = value; directive = endPoint.ToPoint2d() - startPoint.ToPoint2d(); CalcLine(); } }
|
||||
public Point3d CenterPoint { get; private set; }
|
||||
public Vector2d Directive { get => directive; private set => directive = value; }
|
||||
public Vector2d Normal { get => normal; private set => normal = value; }
|
||||
public double A { get; private set; }
|
||||
public double B { get; private set; }
|
||||
public double C { get; private set; }
|
||||
public double k { get; private set; }
|
||||
public double b { get; private set; }
|
||||
public double Length { get => Directive.Norma; }
|
||||
public double cosAlfa { get; private set; }
|
||||
public double cosBeta { get; private set; }
|
||||
public double p { get; private set; }
|
||||
|
||||
public Line2d()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Line2d(Point2d startPt, Point2d endPt)
|
||||
{
|
||||
startPoint = startPt.ToPoint3d(); endPoint = endPt.ToPoint3d();
|
||||
directive = endPoint.ToPoint2d() - startPoint.ToPoint2d();
|
||||
CalcLine();
|
||||
}
|
||||
|
||||
public Line2d(Point3d startPt, Point3d endPt)
|
||||
{
|
||||
startPoint = startPt;
|
||||
endPoint = endPt;
|
||||
directive = endPoint.ToPoint2d() - startPoint.ToPoint2d();
|
||||
CalcLine();
|
||||
}
|
||||
|
||||
protected void CalcLine()
|
||||
{
|
||||
A = Directive.Vy;
|
||||
B = -Directive.Vx;
|
||||
normal = new Vector2d(A, B);
|
||||
C = Directive.Vx * StartPoint.Y - Directive.Vy * StartPoint.X;
|
||||
if (Directive.Vx != 0) { k = Directive.Vy / Directive.Vx; }
|
||||
else { k = Double.PositiveInfinity; }
|
||||
if (Directive.Vx != 0) { b = -Directive.Vy / Directive.Vx * StartPoint.X + StartPoint.Y; }
|
||||
else { b= Double.PositiveInfinity; }
|
||||
double normC = 1 / Math.Sqrt(A * A + B * B);
|
||||
if (C < 0) normC *= -1;
|
||||
cosAlfa = A * normC;
|
||||
cosBeta = B * normC;
|
||||
p = C * normC;
|
||||
double dx = 0.5 * (EndPoint.X - StartPoint.X);
|
||||
double dy = 0.5 * (EndPoint.Y - StartPoint.Y);
|
||||
CenterPoint = new Point3d(StartPoint.X + dx, StartPoint.Y + dy, 0);
|
||||
}
|
||||
|
||||
public double LengthTo(Point2d point)
|
||||
{
|
||||
double normC = 1 / Math.Sqrt(A * A + B * B);
|
||||
if (C < 0) normC *= -1;
|
||||
cosAlfa = A * normC;
|
||||
cosBeta = B * normC;
|
||||
p = C * normC;
|
||||
return normC * (A * point.X + B * point.Y + C);
|
||||
}
|
||||
public double LengthTo(Point3d point)
|
||||
{
|
||||
double normC = 1 / Math.Sqrt(A * A + B * B);
|
||||
if (C < 0) normC *= -1;
|
||||
cosAlfa = A * normC;
|
||||
cosBeta = B * normC;
|
||||
p = C * normC;
|
||||
return normC * (A * point.X + B * point.Y + C);
|
||||
}
|
||||
public double Interpolation(double x)
|
||||
{
|
||||
if (B == 0) return double.PositiveInfinity;
|
||||
else return (-A * x - C) / B;
|
||||
}
|
||||
}
|
||||
}
|
||||
37
Geometry/Line3d.cs
Normal file
37
Geometry/Line3d.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Line3d
|
||||
{
|
||||
Point3d startPoint;
|
||||
Point3d endPoint;
|
||||
|
||||
public Point3d StartPoint { get => startPoint; set { startPoint = value; Directive = endPoint - startPoint; } }
|
||||
public Point3d EndPoint { get => endPoint; set { endPoint = value; Directive = endPoint - startPoint; } }
|
||||
public Vector3d Directive { get; private set; }
|
||||
public double Length { get => Directive.Norma; }
|
||||
|
||||
public Line3d()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Line3d(Point2d startPt, Point2d endPt)
|
||||
{
|
||||
startPoint = startPt.ToPoint3d(); endPoint = endPt.ToPoint3d();
|
||||
Directive = endPoint - startPoint; ;
|
||||
}
|
||||
|
||||
public Line3d(Point3d startPt, Point3d endPt)
|
||||
{
|
||||
startPoint = startPt; endPoint = endPt;
|
||||
Directive = endPoint - startPoint; ;
|
||||
}
|
||||
}
|
||||
}
|
||||
200
Geometry/Matrix.cs
Normal file
200
Geometry/Matrix.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Matrix
|
||||
{
|
||||
double[,] arr;
|
||||
int m, n;
|
||||
public int N
|
||||
{
|
||||
get
|
||||
{
|
||||
if (n > 0)
|
||||
return n;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
public int M
|
||||
{
|
||||
get
|
||||
{
|
||||
if (m > 0)
|
||||
return m;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
public double this[int i, int j]
|
||||
{
|
||||
get
|
||||
{
|
||||
if (n > 0 && m > 0)
|
||||
if (i > -1 && j > -1)
|
||||
return arr[i, j];
|
||||
else
|
||||
Console.WriteLine("Неверный индексы");
|
||||
else
|
||||
Console.WriteLine("Не задана матрица");
|
||||
return -1;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (n > 0 && m > 0)
|
||||
if (i > -1 && j > -1)
|
||||
arr[i, j] = value;
|
||||
else
|
||||
Console.WriteLine("Неверный индексы");
|
||||
else
|
||||
Console.WriteLine("Не задана матрица");
|
||||
}
|
||||
}
|
||||
|
||||
public Matrix(int N, int M)
|
||||
{
|
||||
m = M;
|
||||
n = N;
|
||||
arr = new double[N, M];
|
||||
}
|
||||
|
||||
public Matrix(Matrix source)
|
||||
{
|
||||
m = source.M;
|
||||
n = source.N;
|
||||
arr = new double[source.N, source.M];
|
||||
arr = (double[,])source.arr.Clone();
|
||||
}
|
||||
|
||||
public Matrix(double[,] source)
|
||||
{
|
||||
m = source.GetLength(1);
|
||||
n = source.GetLength(0);
|
||||
arr = new double[source.GetLength(0), source.GetLength(1)];
|
||||
arr = (double[,])source.Clone();
|
||||
}
|
||||
|
||||
public double[,] ToArray()
|
||||
{
|
||||
return arr;
|
||||
}
|
||||
|
||||
public Matrix Copy()
|
||||
{
|
||||
return new Matrix(this);
|
||||
}
|
||||
|
||||
public static Matrix operator ^(Matrix A, Matrix B)
|
||||
{
|
||||
if (A.M != B.N) { throw new System.ArgumentException("Не совпадают размерности матриц"); } //Нужно только одно соответствие
|
||||
Matrix C = new Matrix(A.N, B.M); //Столько же строк, сколько в А; столько столбцов, сколько в B
|
||||
for (int i = 0; i < A.N; ++i)
|
||||
{
|
||||
for (int j = 0; j < B.M; ++j)
|
||||
{
|
||||
C[i, j] = 0;
|
||||
for (int k = 0; k < A.M; ++k)
|
||||
{ //ТРЕТИЙ цикл, до A.m=B.n
|
||||
C[i, j] += A[i, k] * B[k, j]; //Собираем сумму произведений
|
||||
}
|
||||
}
|
||||
}
|
||||
return C;
|
||||
}
|
||||
|
||||
public static Matrix operator *(Matrix A, Matrix B)
|
||||
{
|
||||
if (((A.n != B.n) || (A.m != B.m)) == true) { throw new System.ArgumentException("Не совпадают размерности матриц"); }
|
||||
double[,] res = new double[A.n, B.m];
|
||||
|
||||
for (int i = 0; i < A.n; i++)
|
||||
{
|
||||
for (int j = 0; j < B.m; j++)
|
||||
{
|
||||
res[i, j] = A[i, j] * B[i, j];
|
||||
}
|
||||
}
|
||||
return new Matrix(res);
|
||||
}
|
||||
|
||||
public static Vector operator *(Matrix A, Vector B)
|
||||
{
|
||||
if (A.M != B.N) { throw new System.ArgumentException("Не совпадают размерности матриц"); }
|
||||
double[] res = new double[A.N];
|
||||
|
||||
for (int i = 0; i < A.N; i++)
|
||||
{
|
||||
for (int j = 0; j < B.N; j++)
|
||||
{
|
||||
res[i] += A[i, j] * B[j];
|
||||
}
|
||||
}
|
||||
return new Vector(res);
|
||||
}
|
||||
|
||||
public static Vector3d operator *(Matrix A, Vector3d B)
|
||||
{
|
||||
if (A.n != 3 && A.m != 3) { throw new System.ArgumentException("Не верна размерность матрицы"); }
|
||||
double[] res = new double[3];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
res[i] += A[i, j] * B[j];
|
||||
}
|
||||
}
|
||||
return new Vector3d (res);
|
||||
}
|
||||
|
||||
public static Point3d operator *(Matrix A, Point3d B)
|
||||
{
|
||||
if (A.n != 3 && A.m != 3) { throw new System.ArgumentException("Не верна размерность матрицы"); }
|
||||
double[] res = new double[3];
|
||||
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
{
|
||||
res[i] += A[i, j] * B[j];
|
||||
}
|
||||
}
|
||||
return new Point3d(res);
|
||||
}
|
||||
|
||||
public static Matrix operator *(Matrix A, double B)
|
||||
{
|
||||
double[,] res = new double[A.n, A.m];
|
||||
|
||||
for (int i = 0; i < A.n; i++)
|
||||
{
|
||||
for (int j = 0; j < A.m; j++)
|
||||
{
|
||||
res[i, j] = A[i, j] * B;
|
||||
}
|
||||
}
|
||||
|
||||
return new Matrix(res);
|
||||
}
|
||||
|
||||
public static Matrix operator +(Matrix A, Matrix B)
|
||||
{
|
||||
if (((A.n != B.n) || (A.m != B.m)) == true) { throw new System.ArgumentException("Не совпадают размерности матриц"); }
|
||||
double[,] res = new double[A.n, B.m];
|
||||
|
||||
for (int i = 0; i < A.n; i++)
|
||||
{
|
||||
for (int j = 0; j < B.m; j++)
|
||||
{
|
||||
res[i, j] = A[i, j] + B[i, j];
|
||||
}
|
||||
}
|
||||
return new Matrix(res);
|
||||
}
|
||||
}
|
||||
}
|
||||
242
Geometry/Plane.cs
Normal file
242
Geometry/Plane.cs
Normal file
@@ -0,0 +1,242 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Math;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Plane
|
||||
{
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
double d;
|
||||
double gammaRad;
|
||||
double gammaDeg;
|
||||
|
||||
public double A { get => a; set { a = value; CalcPlane(); } }
|
||||
public double B { get => b; set { b = value; CalcPlane(); } }
|
||||
public double C { get => c; set { c = value; CalcPlane(); } }
|
||||
public double D { get => d; set { d = value; CalcPlane(); } }
|
||||
public double AlfaRad { get; private set; }
|
||||
public double BetaRad { get; private set; }
|
||||
public double GammaRad { get => gammaRad; set { gammaRad = value; RadToDeg(); } }
|
||||
public double AlfaDeg { get; private set; }
|
||||
public double BetaDeg { get; private set; }
|
||||
public double GammaDeg { get => gammaDeg; set { gammaDeg = value; DegToRad(); } }
|
||||
public Matrix MrAlfa { get; private set; }
|
||||
public Matrix MrBeta { get; private set; }
|
||||
public Matrix MrGamma { get; private set; }
|
||||
public Vector3d X1 { get; private set; }
|
||||
public Vector3d Y1 { get; private set; }
|
||||
public Vector3d Z1 { get; private set; }
|
||||
public Vector3d Normal { get; private set; }
|
||||
public Matrix Mr { get; private set; }
|
||||
public Point3d Basis { get; set; }
|
||||
|
||||
public Plane()
|
||||
{
|
||||
Basis = new Point3d() { X = 0, Y = 0, Z = 0 };
|
||||
|
||||
a = 0;
|
||||
b = 0;
|
||||
c = 1;
|
||||
d = 0;
|
||||
|
||||
CalcPlane();
|
||||
}
|
||||
|
||||
public Plane(Point3d pt1, Point3d pt2, Point3d pt3)
|
||||
{
|
||||
Basis = pt1;
|
||||
|
||||
Vector3d v1 = new Vector3d()
|
||||
{
|
||||
Vx = pt2.X - pt1.X,
|
||||
Vy = pt2.Y - pt1.Y,
|
||||
Vz = pt2.Z - pt1.Z
|
||||
};
|
||||
|
||||
Vector3d v2 = new Vector3d()
|
||||
{
|
||||
Vx = pt3.X - pt1.X,
|
||||
Vy = pt3.Y - pt1.Y,
|
||||
Vz = pt3.Z - pt1.Z
|
||||
};
|
||||
|
||||
a = v1.Vy * v2.Vz - v1.Vz * v2.Vy;
|
||||
b = v1.Vz * v2.Vx - v1.Vx * v2.Vz;
|
||||
c = v1.Vx * v2.Vy - v1.Vy * v2.Vx;
|
||||
d = -a * pt1.X - b * pt1.Y - c * pt1.Z;
|
||||
|
||||
CalcPlane();
|
||||
RadToDeg();
|
||||
|
||||
}
|
||||
|
||||
public Plane(Point3d pt1, Point3d pt2, Point3d pt3, Point3d bpt)
|
||||
{
|
||||
Basis = bpt;
|
||||
|
||||
Vector3d v1 = new Vector3d()
|
||||
{
|
||||
Vx = pt2.X - pt1.X,
|
||||
Vy = pt2.Y - pt1.Y,
|
||||
Vz = pt2.Z - pt1.Z
|
||||
};
|
||||
|
||||
Vector3d v2 = new Vector3d()
|
||||
{
|
||||
Vx = pt3.X - pt1.X,
|
||||
Vy = pt3.Y - pt1.Y,
|
||||
Vz = pt3.Z - pt1.Z
|
||||
};
|
||||
|
||||
a = v1.Vy * v2.Vz - v1.Vz * v2.Vy;
|
||||
b = v1.Vz * v2.Vx - v1.Vx * v2.Vz;
|
||||
c = v1.Vx * v2.Vy - v1.Vy * v2.Vx;
|
||||
d = -a * pt1.X - b * pt1.Y - c * pt1.Z;
|
||||
|
||||
CalcPlane();
|
||||
RadToDeg();
|
||||
|
||||
}
|
||||
|
||||
public double Interpolation(double x, double y)
|
||||
{
|
||||
if (C == 0) return double.PositiveInfinity;
|
||||
else return (-A * x - B * y - D) / C;
|
||||
}
|
||||
|
||||
protected void CreatePlane(Point3d pt1, Point3d pt2, Point3d pt3)
|
||||
{
|
||||
Basis = pt1;
|
||||
|
||||
Vector3d v1 = new Vector3d()
|
||||
{
|
||||
Vx = pt2.X - pt1.X,
|
||||
Vy = pt2.Y - pt1.Y,
|
||||
Vz = pt2.Z - pt1.Z
|
||||
};
|
||||
|
||||
Vector3d v2 = new Vector3d()
|
||||
{
|
||||
Vx = pt3.X - pt1.X,
|
||||
Vy = pt3.Y - pt1.Y,
|
||||
Vz = pt3.Z - pt1.Z
|
||||
};
|
||||
|
||||
a = v1.Vy * v2.Vz - v1.Vz * v2.Vy;
|
||||
b = v1.Vz * v2.Vx - v1.Vx * v2.Vz;
|
||||
c = v1.Vx * v2.Vy - v1.Vy * v2.Vx;
|
||||
d = -a * pt1.X - b * pt1.Y - c * pt1.Z;
|
||||
|
||||
CalcPlane();
|
||||
RadToDeg();
|
||||
}
|
||||
|
||||
protected void CalcPlane()
|
||||
{
|
||||
Normal = new Vector3d
|
||||
{
|
||||
Vx = a,
|
||||
Vy = b,
|
||||
Vz = c
|
||||
};
|
||||
|
||||
Intersect();
|
||||
CreateMatrix();
|
||||
|
||||
}
|
||||
|
||||
protected void Intersect()
|
||||
{
|
||||
if ((a == 0 & b == 0) == false)
|
||||
{
|
||||
Vector3d v3 = new Vector3d { Vx = 0, Vy = 0, Vz = 1 };
|
||||
Z1 = new Vector3d(Normal.Unit);
|
||||
X1 = new Vector3d((v3 ^ Z1).Unit);
|
||||
Y1 = new Vector3d((Z1 ^ X1).Unit);
|
||||
|
||||
AlfaRad = -Acos(X1.Vx);
|
||||
BetaRad = -Acos(Z1.Vz);
|
||||
|
||||
//alfaRad = Math.Acos(unitP.Vx);
|
||||
//betaRad = Math.Acos(unitNormal.Vz);
|
||||
}
|
||||
}
|
||||
|
||||
protected void CreateMatrix()
|
||||
{
|
||||
Vector3d o = new Vector3d();
|
||||
o[0] = -X1.Vx * Basis.X - X1.Vy * Basis.Y - X1.Vz * Basis.Z;
|
||||
o[1] = -Y1.Vx * Basis.X - Y1.Vy * Basis.Y - Y1.Vz * Basis.Z;
|
||||
o[2] = -Z1.Vx * Basis.X - Z1.Vy * Basis.Y - Z1.Vz * Basis.Z;
|
||||
|
||||
Mr = new Matrix(4, 4);
|
||||
|
||||
Mr[0, 0] = X1.Vx; Mr[0, 1] = X1.Vy; Mr[0, 2] = X1.Vz; Mr[0, 3] = o.Vx;
|
||||
Mr[1, 0] = Y1.Vx; Mr[1, 1] = Y1.Vy; Mr[1, 2] = Y1.Vz; Mr[1, 3] = o.Vy;
|
||||
Mr[2, 0] = Z1.Vx; Mr[2, 1] = Z1.Vy; Mr[2, 2] = Z1.Vz; Mr[2, 3] = o.Vz;
|
||||
Mr[3, 0] = 0; Mr[3, 1] = 0; Mr[3, 2] = 0; Mr[3, 3] = 1;
|
||||
|
||||
MrAlfa = new Matrix(3, 3);
|
||||
|
||||
MrAlfa[0, 0] = Cos(AlfaRad); MrAlfa[0, 1] = -Sin(AlfaRad); MrAlfa[0, 2] = 0;
|
||||
MrAlfa[1, 0] = Sin(AlfaRad); MrAlfa[1, 1] = Cos(AlfaRad); MrAlfa[1, 2] = 0;
|
||||
MrAlfa[2, 0] = 0; MrAlfa[2, 1] = 0; MrAlfa[2, 2] = 0;
|
||||
|
||||
MrBeta = new Matrix(3, 3);
|
||||
|
||||
MrBeta[0, 0] = 1; MrBeta[0, 1] = 0; MrBeta[0, 2] = 0;
|
||||
MrBeta[1, 0] = 0; MrBeta[1, 1] = Cos(BetaRad); MrBeta[1, 2] = -Sin(BetaRad);
|
||||
MrBeta[2, 0] = 0; MrBeta[2, 1] = Sin(BetaRad); MrBeta[2, 2] = Cos(BetaRad);
|
||||
|
||||
MrGamma = new Matrix(3, 3);
|
||||
|
||||
MrGamma[0, 0] = Cos(gammaRad); MrGamma[0, 1] = -Sin(gammaRad); MrGamma[0, 2] = 0;
|
||||
MrGamma[1, 0] = Sin(gammaRad); MrGamma[1, 1] = Cos(gammaRad); MrGamma[1, 2] = 0;
|
||||
MrGamma[2, 0] = 0; MrGamma[2, 1] = 0; MrGamma[2, 2] = 1;
|
||||
}
|
||||
|
||||
public Point3d PointInLCS(Point3d pt)
|
||||
{
|
||||
double[] d1 = new double[] { 0, 0, 0, 1 }; ;
|
||||
Vector v1 = new Vector(d1);
|
||||
v1[0] = pt.X; v1[1] = pt.Y; v1[2] = pt.Z;
|
||||
|
||||
return new Point3d().FromArray((Mr * v1).ToArray());
|
||||
}
|
||||
|
||||
protected double[] MultiplyMtxVec(double[,] _Matrix, double[] _Vector)
|
||||
{
|
||||
int n = _Vector.Length;
|
||||
double[] _Result = new double[n];
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{
|
||||
for (int j = 0; j < n; j++)
|
||||
{
|
||||
_Result[i] += _Matrix[i, j] * _Vector[j];
|
||||
}
|
||||
}
|
||||
|
||||
return _Result;
|
||||
}
|
||||
|
||||
protected void RadToDeg()
|
||||
{
|
||||
AlfaDeg = AlfaRad * 180 / PI;
|
||||
BetaDeg = BetaRad * 180 / PI;
|
||||
gammaDeg = gammaRad * 180 / PI;
|
||||
}
|
||||
|
||||
protected void DegToRad()
|
||||
{
|
||||
gammaRad = gammaDeg * 180 / PI;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
Geometry/Point2d.cs
Normal file
120
Geometry/Point2d.cs
Normal file
@@ -0,0 +1,120 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Point2d
|
||||
{
|
||||
double[] arr = new double[2];
|
||||
|
||||
public double this[int i] { get => arr[i]; set => arr[i] = value; }
|
||||
public double X { get => arr[0]; set => arr[0] = value; }
|
||||
public double Y { get => arr[1]; set => arr[1] = value; }
|
||||
|
||||
public Point2d()
|
||||
{
|
||||
arr = new double[2];
|
||||
}
|
||||
|
||||
public Point2d(double x, double y)
|
||||
{
|
||||
arr = new double[2];
|
||||
arr[0] = x; arr[1] = y;
|
||||
}
|
||||
|
||||
public Point2d(Point2d source)
|
||||
{
|
||||
arr = new double[2];
|
||||
arr = (double[])source.arr.Clone();
|
||||
}
|
||||
|
||||
public Point2d(Point3d source)
|
||||
{
|
||||
arr = new double[2];
|
||||
arr[0]=source.X; arr[1] = source.Y;
|
||||
}
|
||||
|
||||
public Point2d(double[] source)
|
||||
{
|
||||
arr = new double[2];
|
||||
if (source.Length >= 2)
|
||||
{
|
||||
arr[0] = source[0]; arr[1] = source[1];
|
||||
}
|
||||
}
|
||||
|
||||
public double[] ToArray()
|
||||
{
|
||||
return new double[] { X, Y };
|
||||
}
|
||||
|
||||
public Vector2d ToVector2d()
|
||||
{
|
||||
return new Vector2d { Vx = X, Vy = Y};
|
||||
}
|
||||
|
||||
public Vector3d ToVector3d()
|
||||
{
|
||||
return new Vector3d { Vx = X, Vy = Y, Vz = 0 };
|
||||
}
|
||||
|
||||
public Point3d ToPoint3d()
|
||||
{
|
||||
return new Point3d { X = X, Y = Y, Z = 0 };
|
||||
}
|
||||
|
||||
public Point2d FromArray(double[] arr)
|
||||
{
|
||||
X = arr[0]; Y = arr[1];
|
||||
return this;
|
||||
}
|
||||
|
||||
public double LengthTo(Point2d node)
|
||||
{
|
||||
Line2d line = new Line2d(this, node);
|
||||
return line.Length;
|
||||
}
|
||||
|
||||
public static Vector2d operator -(Point2d pt1, Point2d pt2)
|
||||
{
|
||||
Vector2d res = new Vector2d();
|
||||
res[0] = pt1.X - pt2.X;
|
||||
res[1] = pt1.Y - pt2.Y;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static bool operator ==(Point2d p1, Point2d p2)
|
||||
{
|
||||
bool check = false;
|
||||
if (p1.X == p2.X && p1.Y == p2.Y)
|
||||
{
|
||||
check = true;
|
||||
}
|
||||
return (check);
|
||||
}
|
||||
|
||||
public static bool operator !=(Point2d p1, Point2d p2)
|
||||
{
|
||||
bool check = true;
|
||||
if (p1.X == p2.X && p1.Y == p2.Y)
|
||||
{
|
||||
check = false;
|
||||
}
|
||||
return (check);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
156
Geometry/Point3d.cs
Normal file
156
Geometry/Point3d.cs
Normal file
@@ -0,0 +1,156 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Point3d : IVector
|
||||
{
|
||||
double[] arr;
|
||||
//int n = 3;
|
||||
|
||||
public double this[int i] { get => arr[i]; set => arr[i] = value; }
|
||||
public double X { get => arr[0]; set => arr[0] = value; }
|
||||
public double Y { get => arr[1]; set => arr[1] = value; }
|
||||
public double Z { get => arr[2]; set => arr[2] = value; }
|
||||
|
||||
public int N => 3;
|
||||
|
||||
//int N { get => n; }
|
||||
|
||||
public Point3d()
|
||||
{
|
||||
arr = new double[3];
|
||||
}
|
||||
|
||||
public Point3d(double x, double y, double z)
|
||||
{
|
||||
arr = new double[3];
|
||||
arr[0] = x; arr[1] = y; arr[2] = z;
|
||||
}
|
||||
|
||||
public Point3d(double x, double y)
|
||||
{
|
||||
arr = new double[3];
|
||||
arr[0] = x; arr[1] = y; arr[2] = 0;
|
||||
}
|
||||
|
||||
public Point3d(Point3d source)
|
||||
{
|
||||
arr = new double[3];
|
||||
arr = (double[])source.arr.Clone();
|
||||
}
|
||||
|
||||
public Point3d(double[] source)
|
||||
{
|
||||
arr = new double[3];
|
||||
if (source.Length >= 3) { arr[0] = source[0]; arr[1] = source[1]; arr[2] = source[2]; }
|
||||
else if (source.Length == 2) { arr[0] = source[0]; arr[1] = source[1]; }
|
||||
else { arr[0] = source[0]; }
|
||||
}
|
||||
|
||||
public double[] ToArray()
|
||||
{
|
||||
return new double[] { X, Y, Z };
|
||||
}
|
||||
|
||||
public Vector3d ToVector3d()
|
||||
{
|
||||
return new Vector3d { Vx = X, Vy = Y, Vz = Z };
|
||||
}
|
||||
|
||||
public Point2d ToPoint2d()
|
||||
{
|
||||
return new Point2d { X = X, Y = Y };
|
||||
}
|
||||
|
||||
public Point3d FromArray(double[] arr)
|
||||
{
|
||||
X = arr[0]; Y = arr[1]; Z = arr[2];
|
||||
return this;
|
||||
}
|
||||
|
||||
public double LengthTo(Point3d node)
|
||||
{
|
||||
Line3d line = new Line3d(this, node);
|
||||
return line.Length;
|
||||
}
|
||||
|
||||
public double AngleTo(Point3d startPoint, Point3d endPoint)
|
||||
{
|
||||
Point3d tempNode = new Point3d();
|
||||
|
||||
Line3d tempLine1 = new Line3d(this, startPoint);
|
||||
Line3d tempLine2 = new Line3d(this, endPoint);
|
||||
double cosTo = Vector3d.CosAngleBetVectors(tempLine1.Directive, tempLine2.Directive);
|
||||
return RadToDeg(Math.Acos(cosTo));
|
||||
}
|
||||
|
||||
public bool NormalDirection(Point3d startNode, Point3d endNode)
|
||||
{
|
||||
Line3d tempLine1 = new Line3d(this, startNode);
|
||||
Line3d tempLine2 = new Line3d(this, endNode);
|
||||
double norm = (tempLine1.Directive ^ tempLine2.Directive).Vz;
|
||||
bool res = false;
|
||||
if (norm > 0) res = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
private double RadToDeg(double radians)
|
||||
{
|
||||
return radians * 180 / Math.PI;
|
||||
}
|
||||
|
||||
public static Point3d operator *(Point3d pt, double prime)
|
||||
{
|
||||
return new Point3d
|
||||
{
|
||||
X = pt.X * prime,
|
||||
Y = pt.Y * prime,
|
||||
Z = pt.Z * prime
|
||||
};
|
||||
}
|
||||
|
||||
public static Vector3d operator -(Point3d pt1, Point3d pt2)
|
||||
{
|
||||
Vector3d res = new Vector3d();
|
||||
res[0] = pt1.X - pt2.X;
|
||||
res[1] = pt1.Y - pt2.Y;
|
||||
res[2] = pt1.Z - pt2.Z;
|
||||
return res;
|
||||
}
|
||||
|
||||
public static bool operator ==(Point3d p1, Point3d p2)
|
||||
{
|
||||
bool check = false;
|
||||
if (p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z)
|
||||
{
|
||||
check = true;
|
||||
}
|
||||
return (check);
|
||||
}
|
||||
|
||||
public static bool operator !=(Point3d p1, Point3d p2)
|
||||
{
|
||||
bool check = true;
|
||||
if (p1.X == p2.X && p1.Y == p2.Y && p1.Z == p2.Z)
|
||||
{
|
||||
check = false;
|
||||
}
|
||||
return (check);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return base.GetHashCode();
|
||||
}
|
||||
}
|
||||
}
|
||||
663
Geometry/Polygon.cs
Normal file
663
Geometry/Polygon.cs
Normal file
@@ -0,0 +1,663 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Polygon
|
||||
{
|
||||
private double area;
|
||||
private double ix;
|
||||
private double iy;
|
||||
private List<Point3d> vertices = new List<Point3d>();
|
||||
|
||||
public bool Ckw { get; internal set; }
|
||||
//public bool? IsSelfItersected { get; private set; }
|
||||
public double Area { get => Math.Abs(area); }
|
||||
public double Perimeter { get; internal set; }
|
||||
public Point3d Centroid { get; internal set; }
|
||||
public double Ix { get => Math.Abs(ix); }
|
||||
public double Iy { get => Math.Abs(iy); }
|
||||
public List<Point3d> Vertices { get => vertices; set { vertices = value; CalcPolygon(); } }
|
||||
public BoundingBox2d BoundingBox { get; internal set; }
|
||||
public List<Line2d> Segments { get; internal set; }
|
||||
|
||||
public Polygon()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Polygon(List<Point3d> vrts)
|
||||
{
|
||||
vertices = vrts;
|
||||
if (vertices[0].X != vertices[vrts.Count - 1].X && vertices[0].Y != vertices[vrts.Count - 1].Y) vertices.Add(vertices[0]);
|
||||
CalcPolygon();
|
||||
}
|
||||
|
||||
public Polygon(List<Point2d> vrts)
|
||||
{
|
||||
foreach (Point2d item in vrts) vertices.Add(item.ToPoint3d());
|
||||
if (vertices[0].X != vertices[vrts.Count - 1].X && vertices[0].Y != vertices[vrts.Count - 1].Y) vertices.Add(vertices[0]);
|
||||
CalcPolygon();
|
||||
}
|
||||
|
||||
public virtual void AddVertice(Point2d pt)
|
||||
{
|
||||
if (vertices.Count == 0)
|
||||
{
|
||||
vertices.Add(pt.ToPoint3d());
|
||||
return;
|
||||
}
|
||||
if (vertices.Count == 1)
|
||||
{
|
||||
vertices.Add(pt.ToPoint3d());
|
||||
vertices.Add(vertices[0]);
|
||||
return;
|
||||
}
|
||||
if (vertices.Count >= 3)
|
||||
{
|
||||
vertices.RemoveAt(vertices.Count - 1);
|
||||
vertices.Add(pt.ToPoint3d());
|
||||
vertices.Add(vertices[0]);
|
||||
CalcPolygon();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void AddVertice(Point3d pt)
|
||||
{
|
||||
if (vertices.Count == 0)
|
||||
{
|
||||
vertices.Add(pt);
|
||||
return;
|
||||
}
|
||||
if (vertices.Count == 1)
|
||||
{
|
||||
vertices.Add(pt);
|
||||
vertices.Add(vertices[0]);
|
||||
return;
|
||||
}
|
||||
if (vertices.Count >= 3)
|
||||
{
|
||||
vertices.RemoveAt(vertices.Count - 1);
|
||||
vertices.Add(pt);
|
||||
vertices.Add(vertices[0]);
|
||||
CalcPolygon();
|
||||
}
|
||||
}
|
||||
|
||||
private void CalcBB()
|
||||
{
|
||||
double minX = 1000000000;
|
||||
double minY = 1000000000;
|
||||
double maxX = -1000000000;
|
||||
double maxY = -1000000000;
|
||||
|
||||
if (vertices.Count > 0)
|
||||
{
|
||||
foreach (Point3d item in vertices)
|
||||
{
|
||||
if (item.X < minX) { minX = item.X; }
|
||||
if (item.Y < minY) { minY = item.Y; }
|
||||
if (item.X > maxX) { maxX = item.X; }
|
||||
if (item.Y > maxY) { maxY = item.Y; }
|
||||
}
|
||||
|
||||
BoundingBox = new BoundingBox2d(new Point2d(minX, minY), new Point2d(maxX, maxY));
|
||||
}
|
||||
}
|
||||
|
||||
private void CalcSegs()
|
||||
{
|
||||
if (vertices.Count > 3)
|
||||
{
|
||||
Segments = new List<Line2d>();
|
||||
for (int i = 0; i < vertices.Count - 1; i++)
|
||||
{
|
||||
Segments.Add(new Line2d(vertices[i], vertices[i + 1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void CalcI()
|
||||
{
|
||||
if (Segments.Count > 2)
|
||||
{
|
||||
double tempX = 0;
|
||||
double tempY = 0;
|
||||
for (int i = 0; i < Segments.Count; i++)
|
||||
{
|
||||
Point3d arrTemp = Segments[i].StartPoint; Point3d arrTemp1 = Segments[i].EndPoint;
|
||||
tempX += (Math.Pow(arrTemp.X, 2) + arrTemp.X * arrTemp1.X + Math.Pow(arrTemp1.X, 2)) * (arrTemp.X * arrTemp1.Y - arrTemp.Y * arrTemp1.X);
|
||||
tempY += (Math.Pow(arrTemp.Y, 2) + arrTemp.Y * arrTemp1.Y + Math.Pow(arrTemp1.Y, 2)) * (arrTemp.X * arrTemp1.Y - arrTemp.Y * arrTemp1.X);
|
||||
}
|
||||
ix = tempX / 12;
|
||||
iy = tempY / 12;
|
||||
}
|
||||
}
|
||||
|
||||
protected void CalcCentroid()
|
||||
{
|
||||
if (Segments.Count > 2)
|
||||
{
|
||||
Point3d temp = new Point3d();
|
||||
for (int i = 0; i < Segments.Count; i++)
|
||||
{
|
||||
Point3d arrTemp = Segments[i].StartPoint; Point3d arrTemp1 = Segments[i].EndPoint;
|
||||
temp.X += 1 / (6 * area) * (arrTemp.X + arrTemp1.X) * (arrTemp.X * arrTemp1.Y - arrTemp.Y * arrTemp1.X);
|
||||
temp.Y += 1 / (6 * area) * (arrTemp.Y + arrTemp1.Y) * (arrTemp.X * arrTemp1.Y - arrTemp.Y * arrTemp1.X);
|
||||
}
|
||||
Centroid = temp;
|
||||
}
|
||||
}
|
||||
|
||||
protected void CalcArea()
|
||||
{
|
||||
double temp = 0;
|
||||
if (Segments.Count > 2)
|
||||
{
|
||||
for (int i = 0; i < Segments.Count; i++)
|
||||
{
|
||||
Point3d arrTemp = Segments[i].StartPoint; Point3d arrTemp1 = Segments[i].EndPoint;
|
||||
temp += 0.5 * (arrTemp.X * arrTemp1.Y - arrTemp1.X * arrTemp.Y);
|
||||
}
|
||||
area = temp;
|
||||
}
|
||||
}
|
||||
|
||||
protected void CalcPerimeter()
|
||||
{
|
||||
if (Segments.Count > 2)
|
||||
{
|
||||
Perimeter = 0;
|
||||
foreach (Line2d item in Segments)
|
||||
{
|
||||
Perimeter += item.Length;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void CalcCkw()
|
||||
{
|
||||
if (area < 0) Ckw = true;
|
||||
else Ckw = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вычисление свойств полигона
|
||||
/// </summary>
|
||||
public void CalcPolygon()
|
||||
{
|
||||
if (Vertices.Count > 3)
|
||||
{
|
||||
if ((Vertices[0].X != Vertices[vertices.Count - 1].X && Vertices[0].Y != Vertices[Vertices.Count - 1].Y)||
|
||||
(Vertices[0].X == Vertices[vertices.Count - 1].X && Vertices[0].Y != Vertices[Vertices.Count - 1].Y)||
|
||||
(Vertices[0].X != Vertices[vertices.Count - 1].X && Vertices[0].Y == Vertices[Vertices.Count - 1].Y))
|
||||
Vertices.Add(Vertices[0]);
|
||||
}
|
||||
CalcBB();
|
||||
CalcSegs();
|
||||
CalcPerimeter();
|
||||
CalcArea();
|
||||
CalcCkw();
|
||||
CalcCentroid();
|
||||
CalcI();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Замена вершины полигона
|
||||
/// </summary>
|
||||
/// <param name="oldVertIdx">индекс заменяемой вершины</param>
|
||||
/// <param name="newVert">объект заменяющей вершины</param>
|
||||
public bool ReplaceVertice( int oldVertIdx, Point3d newVert)
|
||||
{
|
||||
try
|
||||
{
|
||||
Vertices[oldVertIdx] = newVert;
|
||||
if (oldVertIdx == 0 || oldVertIdx == Vertices.Count - 1) { Vertices[0] = newVert; Vertices[Vertices.Count - 1] = newVert; }
|
||||
CalcPolygon();
|
||||
return true;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void Triangulation(double shag, out List<Point3d> innerNodes, out List<Triangle> triangles)
|
||||
{
|
||||
innerNodes = new List<Point3d>();
|
||||
triangles = new List<Triangle>();
|
||||
List<Polygon> polygons = new List<Polygon>();
|
||||
int n = Tesselation(shag);
|
||||
Polygon front = new Polygon(Vertices);
|
||||
//int p = 1;
|
||||
do
|
||||
{
|
||||
if (polygons.Count != 0) { front = polygons[0]; polygons.RemoveAt(0); }
|
||||
for (int j = 0; j < 1000; j++)
|
||||
{
|
||||
AngleIn3Point minAngle;
|
||||
front.MinAngleDeg(out minAngle);
|
||||
while (minAngle.AngleDeg == 0 && front.Vertices.Count > 3)
|
||||
{
|
||||
if(minAngle.VerticeIdx == 0)
|
||||
{
|
||||
front.Vertices.RemoveRange(Vertices.Count - 2, 2);
|
||||
front.Vertices.RemoveAt(0);
|
||||
}
|
||||
else front.Vertices.RemoveRange(minAngle.PreviousIdx, 2);
|
||||
front.CalcPolygon();
|
||||
front.MinAngleDeg(out minAngle);
|
||||
}
|
||||
|
||||
if (Math.Round(minAngle.AngleDeg) < 90)
|
||||
{
|
||||
triangles.Add(new Triangle(front.Vertices[minAngle.PreviousIdx], front.Vertices[minAngle.VerticeIdx], front.Vertices[minAngle.NextIdx]));
|
||||
front.Vertices.RemoveAt(minAngle.VerticeIdx);
|
||||
if (minAngle.VerticeIdx == 0 && front.Vertices.Count > 3) front.Vertices.RemoveAt(front.Vertices.Count - 1);
|
||||
front.CalcPolygon();
|
||||
}
|
||||
|
||||
else if (Math.Round(minAngle.AngleDeg) == 90 /*&& Math.Round(minAngle.AngleDeg) <= 140*/)
|
||||
{
|
||||
Line2d lin = new Line2d(front.Vertices[minAngle.VerticeIdx], front.Vertices[minAngle.PreviousIdx]);
|
||||
Point3d temp = front.Vertices[minAngle.VerticeIdx];
|
||||
Point3d g = new Point3d(front.Vertices[minAngle.NextIdx].X + lin.Directive.Vx, front.Vertices[minAngle.NextIdx].Y + lin.Directive.Vy, 0);
|
||||
Point3d gNode = new Point3d { X = g.X, Y = g.Y, Z = g.Z/*, Number = n*/ };
|
||||
bool ch = false;
|
||||
int k = -1;
|
||||
for (int i = 0; i < front.Vertices.Count - 1; i++)
|
||||
{
|
||||
//if (i == minAngle.VerticeIdx) continue;
|
||||
double d = g.LengthTo(front.Vertices[i]);
|
||||
if (Math.Round(g.X, 2) == Math.Round(front.Vertices[i].X, 2) && Math.Round(g.Y, 2) == Math.Round(front.Vertices[i].Y, 2))
|
||||
{ ch = true; k = i; break; }
|
||||
}
|
||||
|
||||
Triangle t1, t2;
|
||||
|
||||
if (ch)
|
||||
{
|
||||
t1 = new Triangle(front.Vertices[minAngle.VerticeIdx], front.Vertices[minAngle.NextIdx], front.Vertices[k]);
|
||||
t2 = new Triangle(front.Vertices[minAngle.PreviousIdx], front.Vertices[minAngle.VerticeIdx], front.Vertices[k]);
|
||||
}
|
||||
else
|
||||
{
|
||||
t1 = new Triangle(front.Vertices[minAngle.VerticeIdx], front.Vertices[minAngle.NextIdx], gNode);
|
||||
t2 = new Triangle(front.Vertices[minAngle.PreviousIdx], front.Vertices[minAngle.VerticeIdx], gNode);
|
||||
}
|
||||
|
||||
front.ReplaceVertice(minAngle.VerticeIdx, gNode);
|
||||
|
||||
if (front.SelfItersectCheck())
|
||||
{
|
||||
front.ReplaceVertice(minAngle.VerticeIdx, temp);
|
||||
double dist = 100000000;
|
||||
k = -1;
|
||||
for (int i = 0; i < front.Vertices.Count - 1; i++)
|
||||
{
|
||||
if (i == minAngle.NextIdx || i == minAngle.PreviousIdx || i == minAngle.VerticeIdx) continue;
|
||||
double d = front.Vertices[minAngle.VerticeIdx].LengthTo(front.Vertices[i]);
|
||||
if (d < dist) { dist = d; k = i; }
|
||||
}
|
||||
Polygon sub;
|
||||
front.Bisection(k, minAngle.VerticeIdx, out sub);
|
||||
polygons.Add(sub);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ch) { innerNodes.Add(gNode); n++; }
|
||||
triangles.Add(t1); triangles.Add(t2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
Line2d linPrev = new Line2d(front.Vertices[minAngle.VerticeIdx], front.Vertices[minAngle.PreviousIdx]);
|
||||
Line2d linNext = new Line2d(front.Vertices[minAngle.VerticeIdx], front.Vertices[minAngle.NextIdx]);
|
||||
double vx = (linPrev.Directive.Unit[0] + linNext.Directive.Unit[0]) * 0.5;
|
||||
double vy = (linPrev.Directive.Unit[1] + linNext.Directive.Unit[1]) * 0.5;
|
||||
//double lengthBis = (linPrev.Length + linNext.Length) * 0.5;
|
||||
double x = front.Vertices[minAngle.VerticeIdx].X + vx * shag;
|
||||
double y = front.Vertices[minAngle.VerticeIdx].Y + vy * shag;
|
||||
Point3d temp = front.Vertices[minAngle.VerticeIdx];
|
||||
Point3d g = new Point3d(x, y, 0);
|
||||
Line2d linBis = new Line2d(front.Vertices[minAngle.VerticeIdx], g);
|
||||
x = front.Vertices[minAngle.VerticeIdx].X + linBis.Directive.Unit[0] * shag;
|
||||
y = front.Vertices[minAngle.VerticeIdx].Y + linBis.Directive.Unit[1] * shag;
|
||||
g = new Point3d(x, y, 0);
|
||||
Point3d gNode = new Point3d() { X = g.X, Y = g.Y, Z = g.Z/*, Number = n*/ };
|
||||
Triangle t1, t2;
|
||||
t1 = new Triangle(front.Vertices[minAngle.VerticeIdx], front.Vertices[minAngle.NextIdx], gNode);
|
||||
t2 = new Triangle(front.Vertices[minAngle.PreviousIdx], front.Vertices[minAngle.VerticeIdx], gNode);
|
||||
front.ReplaceVertice(minAngle.VerticeIdx, gNode);
|
||||
//if (p == 1) { Shpunt.AcCreator.CreateContour(front); p++; }
|
||||
|
||||
if (front.SelfItersectCheck())
|
||||
{
|
||||
front.ReplaceVertice(minAngle.VerticeIdx, temp);
|
||||
double dist = 100000000;
|
||||
int k = -1;
|
||||
for (int i = 0; i < front.Vertices.Count - 1; i++)
|
||||
{
|
||||
if (i == minAngle.NextIdx || i == minAngle.PreviousIdx || i == minAngle.VerticeIdx) continue;
|
||||
double d = front.Vertices[minAngle.VerticeIdx].LengthTo(front.Vertices[i]);
|
||||
if (d < dist) { dist = d; k = i; }
|
||||
}
|
||||
Polygon sub;
|
||||
front.Bisection(k, minAngle.VerticeIdx, out sub);
|
||||
polygons.Add(sub);
|
||||
}
|
||||
else
|
||||
{
|
||||
triangles.Add(t1);
|
||||
triangles.Add(t2);
|
||||
innerNodes.Add(gNode);
|
||||
}
|
||||
n++;
|
||||
}
|
||||
if (front.Vertices.Count < 4) break;
|
||||
}
|
||||
} while (polygons.Count != 0);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Тесселяция полигона с заданным шагом
|
||||
/// </summary>
|
||||
/// <param name="shag"> Величина шага тесселяции</param>
|
||||
public int Tesselation(double shag)
|
||||
{
|
||||
List<Point3d> nodes = new List<Point3d>();
|
||||
int n = 1;
|
||||
int nD = 0;
|
||||
foreach (Line2d seg in Segments)
|
||||
{
|
||||
Point3d start = seg.StartPoint;
|
||||
Point3d end = seg.EndPoint;
|
||||
nD = (int)Math.Round(seg.Length / shag);
|
||||
if (nD > 1)
|
||||
{
|
||||
double delta = seg.Length / nD;
|
||||
double deltaX = (end.X - start.X) / nD;
|
||||
double deltaY = (end.Y - start.Y) / nD;
|
||||
double deltaZ = (end.Z - start.Z) / nD;
|
||||
for (int j = 0; j < nD; j++)
|
||||
{
|
||||
Point3d pt = new Point3d(start.X + j * deltaX, start.Y + j * deltaY, start.Z + j * deltaZ);
|
||||
//FEA.Node nd = new FEA.Node(pt) { Number = n };
|
||||
nodes.Add(pt);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Point3d pt = new Point3d(start.X, start.Y, start.Z);
|
||||
//FEA.Node nd = new FEA.Node(pt) { Number = n };
|
||||
nodes.Add(pt);
|
||||
n++;
|
||||
}
|
||||
}
|
||||
Vertices = nodes;
|
||||
if (!Ckw) { Vertices.Reverse(); CalcPolygon(); }
|
||||
return n;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Деление полигона через указание 2-х точек деления
|
||||
/// </summary>
|
||||
/// <param name="sectPointIdx">Индекс первой точки деления(секущей)</param>
|
||||
/// <param name="basePointIdx">Индекс второй точки деления(базовой)</param>
|
||||
/// <param name="newPolygon">Возвращаемый отсеченный полигон</param>
|
||||
public void Bisection(int sectPointIdx,int basePointIdx, out Polygon newPolygon)
|
||||
{
|
||||
newPolygon = new Polygon();
|
||||
List<Point3d> tmp = new List<Point3d>();
|
||||
if (basePointIdx > sectPointIdx)
|
||||
{
|
||||
for (int i = sectPointIdx; i <= basePointIdx; i++)
|
||||
{
|
||||
newPolygon.AddVertice(Vertices[i]);
|
||||
}
|
||||
newPolygon.CalcPolygon();
|
||||
Vertices.RemoveRange(sectPointIdx + 1, basePointIdx - sectPointIdx - 1);
|
||||
CalcPolygon();
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = basePointIdx; i <= sectPointIdx; i++)
|
||||
{
|
||||
newPolygon.AddVertice(Vertices[i]);
|
||||
}
|
||||
newPolygon.CalcPolygon();
|
||||
Vertices.RemoveRange(basePointIdx + 1, sectPointIdx - basePointIdx - 1);
|
||||
CalcPolygon();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверка полигона на самопересечение (возвращает булево значение, если true - полигон самопересекающийся)
|
||||
/// </summary>
|
||||
public bool SelfItersectCheck()
|
||||
{
|
||||
bool IsSelfItersected = false;
|
||||
if (Segments.Count < 4) return IsSelfItersected;
|
||||
for (int i = 0; i < Segments.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < Segments.Count; j++)
|
||||
{
|
||||
if (i == j) continue;
|
||||
double a1 = Segments[i].A;
|
||||
double a2 = Segments[j].A;
|
||||
double b1 = Segments[i].B;
|
||||
double b2 = Segments[j].B;
|
||||
double c1 = Segments[i].C;
|
||||
double c2 = Segments[j].C;
|
||||
double p1 = (b2 - b1 * a2 / a1);
|
||||
if (p1 == 0) continue;
|
||||
double y = (a2 * c1 / a1 - c2) / p1;
|
||||
double x = (-b1 * y - c1) / a1;
|
||||
Point3d ptItersect = new Point3d(x, y, 0);
|
||||
Line2d linTmp1 = new Line2d(Segments[i].CenterPoint, ptItersect);
|
||||
Line2d linTmp2 = new Line2d(Segments[j].CenterPoint, ptItersect);
|
||||
double l1 = Math.Round(linTmp1.Length, 2);
|
||||
double l11 = Math.Round(Segments[i].Length / 2, 2);
|
||||
double l2 = Math.Round(linTmp2.Length, 2);
|
||||
double l22 = Math.Round(Segments[j].Length / 2, 2);
|
||||
if (Math.Round(linTmp1.Length, 2) < Math.Round(Segments[i].Length / 2, 2) &&
|
||||
Math.Round(linTmp2.Length, 2) < Math.Round(Segments[j].Length / 2, 2))
|
||||
{
|
||||
IsSelfItersected = true;
|
||||
return IsSelfItersected;
|
||||
}
|
||||
}
|
||||
}
|
||||
return IsSelfItersected;
|
||||
}
|
||||
/// <summary>
|
||||
/// Вычисление минимального угла полигона в градусах
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public double MinAngleDeg()
|
||||
{
|
||||
double minAngle = 360;
|
||||
double angleTmp;
|
||||
bool type;
|
||||
for (int i = 0; i < Vertices.Count - 1; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
angleTmp = Vertices[0].AngleTo(Vertices[Vertices.Count - 2], Vertices[1]);
|
||||
if (angleTmp is double.NaN) angleTmp = 180;
|
||||
type = Vertices[0].NormalDirection(Vertices[Vertices.Count - 2], Vertices[1]);
|
||||
if (!type && angleTmp != 0) angleTmp = 360 - angleTmp;
|
||||
if (!type && angleTmp == 0) angleTmp = 0;
|
||||
if (angleTmp < minAngle) minAngle = angleTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
angleTmp = Vertices[i].AngleTo(Vertices[i - 1], Vertices[i + 1]);
|
||||
if (angleTmp is double.NaN) angleTmp = 180;
|
||||
type = Vertices[i].NormalDirection(Vertices[i - 1], Vertices[i + 1]);
|
||||
if (!type && angleTmp != 0) angleTmp = 360 - angleTmp;
|
||||
if (!type && angleTmp == 0) angleTmp = 0;
|
||||
if (angleTmp < minAngle) minAngle = angleTmp;
|
||||
}
|
||||
}
|
||||
return minAngle;
|
||||
}
|
||||
/// <summary>
|
||||
/// Вычисление минимального угла полигона в градусах (возвращает массив индексов 3-х точек на которых был найден угол)
|
||||
/// </summary>
|
||||
/// <param name="minAngle"> Возвращаемое значение минимального угла в градусах </param>
|
||||
public int[] MinAngleDeg(out double minAngle)
|
||||
{
|
||||
minAngle = 0;
|
||||
if (Vertices.Count < 3) return null;
|
||||
int[] res = new int[3];
|
||||
minAngle = 360;
|
||||
double angleTmp;
|
||||
bool type;
|
||||
for (int i = 0; i < Vertices.Count - 1; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
angleTmp = Vertices[0].AngleTo(Vertices[Vertices.Count - 2], Vertices[i + 1]);
|
||||
if (angleTmp is double.NaN) angleTmp = 180;
|
||||
type = Vertices[i].NormalDirection(Vertices[Vertices.Count - 2], Vertices[i + 1]);
|
||||
if (!type && angleTmp != 0) angleTmp = 360 - angleTmp;
|
||||
if (!type && angleTmp == 0) angleTmp = 0;
|
||||
if (angleTmp < minAngle)
|
||||
{
|
||||
res[0] = Vertices.Count - 2;
|
||||
res[1] = 0;
|
||||
res[2] = 1;
|
||||
minAngle = angleTmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
angleTmp = Vertices[i].AngleTo(Vertices[i - 1], Vertices[i + 1]);
|
||||
if (angleTmp is double.NaN) angleTmp = 180;
|
||||
type = Vertices[i].NormalDirection(Vertices[i - 1], Vertices[i + 1]);
|
||||
if (!type && angleTmp != 0) angleTmp = 360 - angleTmp;
|
||||
if (!type && angleTmp == 0) angleTmp = 0;
|
||||
if (angleTmp < minAngle)
|
||||
{
|
||||
res[0] = i - 1;
|
||||
res[1] = i;
|
||||
res[2] = i + 1;
|
||||
minAngle = angleTmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Вычисление минимального угла полигона в градусах
|
||||
/// </summary>
|
||||
/// <param name="result">Возвращаемое значение в виде объекта со свойствами индексов трех точек образуюших угол и значения угла в градусах</param>
|
||||
public void MinAngleDeg(out AngleIn3Point result)
|
||||
{
|
||||
result = new AngleIn3Point();
|
||||
result.AngleDeg = 0;
|
||||
if (Vertices.Count < 3) return;
|
||||
result.AngleDeg = 360;
|
||||
double angleTmp;
|
||||
bool type;
|
||||
for (int i = 0; i < Vertices.Count - 1; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
angleTmp = Vertices[0].AngleTo(Vertices[Vertices.Count - 2], Vertices[i + 1]);
|
||||
if (angleTmp is double.NaN) angleTmp = 180;
|
||||
type = Vertices[i].NormalDirection(Vertices[Vertices.Count - 2], Vertices[i + 1]);
|
||||
if (!type && angleTmp != 0) angleTmp = 360 - angleTmp;
|
||||
if (!type && angleTmp == 0) angleTmp = 0;
|
||||
if (angleTmp < result.AngleDeg)
|
||||
{
|
||||
result.PreviousIdx = Vertices.Count - 2;
|
||||
result.VerticeIdx = 0;
|
||||
result.NextIdx = 1;
|
||||
result.AngleDeg = angleTmp;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
angleTmp = Vertices[i].AngleTo(Vertices[i - 1], Vertices[i + 1]);
|
||||
if (angleTmp is double.NaN) angleTmp = 180;
|
||||
type = Vertices[i].NormalDirection(Vertices[i - 1], Vertices[i + 1]);
|
||||
if (!type && angleTmp != 0) angleTmp = 360 - angleTmp;
|
||||
if (!type && angleTmp == 0) angleTmp = 0;
|
||||
if (angleTmp < result.AngleDeg)
|
||||
{
|
||||
result.PreviousIdx = i - 1;
|
||||
result.VerticeIdx = i;
|
||||
result.NextIdx = i + 1;
|
||||
result.AngleDeg = angleTmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Вычисление максимального угла полигона в градусах
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public double MaxAngleDeg()
|
||||
{
|
||||
double minAngle = 0;
|
||||
double angleTmp;
|
||||
bool type;
|
||||
for (int i = 0; i < Vertices.Count - 1; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
{
|
||||
angleTmp = Vertices[0].AngleTo(Vertices[Vertices.Count - 2], Vertices[i + 1]);
|
||||
if (angleTmp is double.NaN) angleTmp = 180;
|
||||
type = Vertices[i].NormalDirection(Vertices[Vertices.Count - 2], Vertices[i + 1]);
|
||||
if (!type && angleTmp != 0) angleTmp = 360 - angleTmp;
|
||||
if (!type && angleTmp == 0) angleTmp = 0;
|
||||
if (angleTmp > minAngle) minAngle = angleTmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
angleTmp = Vertices[i].AngleTo(Vertices[i - 1], Vertices[i + 1]);
|
||||
if (angleTmp is double.NaN) angleTmp = 180;
|
||||
type = Vertices[i].NormalDirection(Vertices[i - 1], Vertices[i + 1]);
|
||||
if (!type && angleTmp != 0) angleTmp = 360 - angleTmp;
|
||||
if (!type && angleTmp == 0) angleTmp = 0;
|
||||
if (angleTmp > minAngle) minAngle = angleTmp;
|
||||
}
|
||||
}
|
||||
|
||||
return minAngle;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Объект-структура со свойствами индексов трех точек образуюших угол и значения угла в градусах
|
||||
/// </summary>
|
||||
public struct AngleIn3Point
|
||||
{
|
||||
/// <summary>
|
||||
/// Индекс предыдущей вершины
|
||||
/// </summary>
|
||||
public int PreviousIdx { get; set; }
|
||||
/// <summary>
|
||||
/// Индех следующей вершины
|
||||
/// </summary>
|
||||
public int NextIdx { get; set; }
|
||||
/// <summary>
|
||||
/// Индекс вершины, на которой найден угол
|
||||
/// </summary>
|
||||
public int VerticeIdx { get; set; }
|
||||
/// <summary>
|
||||
/// Значение найденного угла в градусах
|
||||
/// </summary>
|
||||
public double AngleDeg { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
147
Geometry/Quadrangle.cs
Normal file
147
Geometry/Quadrangle.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Quadrangle : Polygon
|
||||
{
|
||||
private Point3d vertex1 = new Point3d();
|
||||
private Point3d vertex2 = new Point3d();
|
||||
private Point3d vertex3 = new Point3d();
|
||||
private Point3d vertex4 = new Point3d();
|
||||
|
||||
public Point3d Vertex1 { get => vertex1; set { vertex1 = value; Vertices[0] = vertex1; CalcQuadrangle(); } }
|
||||
public Point3d Vertex2 { get => vertex2; set { vertex2 = value; Vertices[1] = vertex2; CalcQuadrangle(); } }
|
||||
public Point3d Vertex3 { get => vertex3; set { vertex3 = value; Vertices[2] = vertex3; CalcQuadrangle(); } }
|
||||
public Point3d Vertex4 { get => vertex4; set { vertex4 = value; Vertices[3] = vertex4; CalcQuadrangle(); } }
|
||||
public double MaxAngleDeg { get; private set; }
|
||||
public bool IsValid { get; private set; }
|
||||
public UnitsLin Units { get; set; }
|
||||
|
||||
public Quadrangle(Triangle trg1, Triangle trg2)
|
||||
{
|
||||
List<Point3d> vrt = new List<Point3d>();
|
||||
List<Point3d> dgn = new List<Point3d>();
|
||||
vrt.Add(trg1.Vertex1);
|
||||
vrt.Add(trg1.Vertex2);
|
||||
vrt.Add(trg1.Vertex3);
|
||||
vrt.Add(trg2.Vertex1);
|
||||
vrt.Add(trg2.Vertex2);
|
||||
vrt.Add(trg2.Vertex3);
|
||||
for (int i = 0; i < vrt.Count; i++)
|
||||
{
|
||||
for (int j = 0; j < vrt.Count; j++)
|
||||
{
|
||||
if (i == j) continue;
|
||||
if (Math.Round(vrt[i].X, 2) == Math.Round(vrt[j].X,2) && Math.Round(vrt[i].Y,2) == Math.Round(vrt[j].Y,2))
|
||||
{
|
||||
dgn.Add(vrt[i]);
|
||||
vrt.RemoveAt(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (vrt.Count == 4)
|
||||
{
|
||||
if (vrt[0].Equals(dgn[0]) && vrt[1].Equals(dgn[1]))
|
||||
{
|
||||
vertex1 = vrt[0];
|
||||
AddVertice(Vertex1);
|
||||
vertex2 = vrt[2];
|
||||
AddVertice(Vertex2);
|
||||
vertex3 = vrt[1];
|
||||
AddVertice(Vertex3);
|
||||
vertex4 = vrt[3];
|
||||
AddVertice(Vertex4);
|
||||
}
|
||||
if (vrt[1].Equals(dgn[0]) && vrt[2].Equals(dgn[1]))
|
||||
{
|
||||
vertex1 = vrt[0];
|
||||
AddVertice(Vertex1);
|
||||
vertex2 = vrt[2];
|
||||
AddVertice(Vertex2);
|
||||
vertex3 = vrt[3];
|
||||
AddVertice(Vertex3);
|
||||
vertex4 = vrt[1];
|
||||
AddVertice(Vertex4);
|
||||
}
|
||||
if (vrt[0].Equals(dgn[0]) && vrt[2].Equals(dgn[1]))
|
||||
{
|
||||
vertex1 = vrt[0];
|
||||
AddVertice(Vertex1);
|
||||
vertex2 = vrt[1];
|
||||
AddVertice(Vertex2);
|
||||
vertex3 = vrt[2];
|
||||
AddVertice(Vertex3);
|
||||
vertex4 = vrt[3];
|
||||
AddVertice(Vertex4);
|
||||
}
|
||||
if (vrt[1].Equals(dgn[0]) && vrt[3].Equals(dgn[1]))
|
||||
{
|
||||
vertex1 = vrt[0];
|
||||
AddVertice(Vertex1);
|
||||
vertex2 = vrt[1];
|
||||
AddVertice(Vertex2);
|
||||
vertex3 = vrt[2];
|
||||
AddVertice(Vertex3);
|
||||
vertex4 = vrt[3];
|
||||
AddVertice(Vertex4);
|
||||
}
|
||||
IsValid = true;
|
||||
CalcQuadrangle();
|
||||
}
|
||||
else
|
||||
{
|
||||
IsValid = false;
|
||||
Vertices.Add(new Point3d());
|
||||
Vertices.Add(new Point3d());
|
||||
Vertices.Add(new Point3d());
|
||||
Vertices.Add(new Point3d());
|
||||
}
|
||||
}
|
||||
|
||||
public Quadrangle(Point3d node1, Point3d node2, Point3d node3, Point3d node4)
|
||||
{
|
||||
vertex1 = node1;
|
||||
AddVertice(node1);
|
||||
vertex2 = node2;
|
||||
AddVertice(node2);
|
||||
vertex3 = node3;
|
||||
AddVertice(node3);
|
||||
vertex4 = node4;
|
||||
AddVertice(node4);
|
||||
CalcQuadrangle();
|
||||
IsValid = true;
|
||||
}
|
||||
|
||||
public Quadrangle(Point2d node1, Point2d node2, Point2d node3, Point2d node4)
|
||||
{
|
||||
vertex1 = node1.ToPoint3d();
|
||||
AddVertice(node1);
|
||||
vertex2 = node2.ToPoint3d();
|
||||
AddVertice(node2);
|
||||
vertex3 = node3.ToPoint3d();
|
||||
AddVertice(node3);
|
||||
vertex4 = node4.ToPoint3d();
|
||||
AddVertice(node4);
|
||||
CalcQuadrangle();
|
||||
IsValid = true;
|
||||
}
|
||||
|
||||
public void CalcQuadrangle()
|
||||
{
|
||||
double ang1, ang2, ang3, ang4;
|
||||
ang1 = vertex1.AngleTo(vertex4, vertex2);
|
||||
ang2 = vertex2.AngleTo(vertex1, vertex3);
|
||||
ang3 = vertex3.AngleTo(vertex2, vertex4);
|
||||
ang4 = vertex4.AngleTo(vertex3, vertex1);
|
||||
MaxAngleDeg = Math.Max(Math.Max(Math.Max(ang1, ang2), ang3), ang4);
|
||||
CalcPolygon();
|
||||
}
|
||||
}
|
||||
}
|
||||
67
Geometry/Triangle.cs
Normal file
67
Geometry/Triangle.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Triangle : Polygon
|
||||
{
|
||||
private Point3d vertex1;
|
||||
private Point3d vertex2;
|
||||
private Point3d vertex3;
|
||||
|
||||
public Point3d Vertex1 { get => vertex1; set { vertex1 = value; Vertices[0] = vertex1; CalcTriangle(); } }
|
||||
public Point3d Vertex2 { get => vertex2; set { vertex2 = value; Vertices[1] = vertex2; CalcTriangle(); } }
|
||||
public Point3d Vertex3 { get => vertex3; set { vertex3 = value; Vertices[2] = vertex3; CalcTriangle(); } }
|
||||
public double MaxAngleDeg { get; private set; }
|
||||
|
||||
public Triangle(Point3d node1, Point3d node2, Point3d node3)
|
||||
{
|
||||
vertex1 = node1;
|
||||
AddVertice(vertex1);
|
||||
vertex2 = node2;
|
||||
AddVertice(vertex2);
|
||||
vertex3 = node3;
|
||||
AddVertice(vertex3);
|
||||
CalcTriangle();
|
||||
}
|
||||
|
||||
public Triangle(Point2d node1, Point2d node2, Point2d node3)
|
||||
{
|
||||
vertex1 = node1.ToPoint3d();
|
||||
AddVertice(vertex1);
|
||||
vertex2 = node2.ToPoint3d();
|
||||
AddVertice(vertex2);
|
||||
vertex3 = node3.ToPoint3d();
|
||||
AddVertice(vertex3);
|
||||
CalcTriangle();
|
||||
}
|
||||
|
||||
public void CalcTriangle()
|
||||
{
|
||||
//Edge1 = new Line3d(vertex1, vertex2);
|
||||
//Edge2 = new Line3d(vertex2, vertex3);
|
||||
//Edge3 = new Line3d(vertex3, vertex1);
|
||||
//Centroid = new Point3d((vertex1.X + vertex2.X + vertex3.X) / 3, (vertex1.Y + vertex2.Y + vertex3.Y) / 3, (vertex1.Z + vertex2.Z + vertex3.Z) / 3);
|
||||
//Point3d minPt, maxPt;
|
||||
//minPt = new Point3d(
|
||||
// Math.Min(Math.Min(vertex1.X, vertex2.X), vertex3.X),
|
||||
// Math.Min(Math.Min(vertex1.Y, vertex2.Y), vertex3.Y),
|
||||
// Math.Min(Math.Min(vertex1.Z, vertex2.Z), vertex3.Z));
|
||||
//maxPt = new Point3d(
|
||||
// Math.Max(Math.Max(vertex1.X, vertex2.X), vertex3.X),
|
||||
// Math.Max(Math.Max(vertex1.Y, vertex2.Y), vertex3.Y),
|
||||
// Math.Max(Math.Max(vertex1.Z, vertex2.Z), vertex3.Z));
|
||||
//BoundingBox = new BoundingBox2d(minPt.ToPoint2d(), maxPt.ToPoint2d());
|
||||
double ang1, ang2, ang3;
|
||||
ang1 = vertex1.AngleTo(vertex3, vertex2);
|
||||
ang2 = vertex2.AngleTo(vertex1, vertex3);
|
||||
ang3 = vertex3.AngleTo(vertex2, vertex1);
|
||||
MaxAngleDeg = Math.Max(Math.Max(ang1, ang2), ang3);
|
||||
CalcPolygon();
|
||||
}
|
||||
}
|
||||
}
|
||||
11
Geometry/UnitsEnums.cs
Normal file
11
Geometry/UnitsEnums.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
public enum UnitsLin { м = 1, см = 2, мм = 3, _ = 0 }
|
||||
public enum UnitsArea { м = 1, см = 2, мм = 3, _ = 0 }
|
||||
public enum UnitsForce { т = 1, кН = 3, Н = 4, кг = 2, _ = 0 }
|
||||
public enum UnitsStress { т = 1, кН = 2, Н = 3, МПа = 4, кПа = 5, _ = 0 }
|
||||
public enum UnitsList { _, м, см, мм, т, кг, Н, кН, кПа, МПа, градус, rad }
|
||||
57
Geometry/Vector.cs
Normal file
57
Geometry/Vector.cs
Normal file
@@ -0,0 +1,57 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Vector : IVector
|
||||
{
|
||||
double[] arr;
|
||||
int n;
|
||||
|
||||
public int N { get => n; }
|
||||
public double this[int i] { get => arr[i]; set => arr[i] = value; }
|
||||
|
||||
public Vector(int N)
|
||||
{
|
||||
n = N;
|
||||
arr = new double[N];
|
||||
}
|
||||
|
||||
public Vector(Vector source)
|
||||
{
|
||||
n = source.N;
|
||||
arr = new double[source.N];
|
||||
arr = (double[])source.arr.Clone();
|
||||
}
|
||||
|
||||
public Vector(Vector3d source)
|
||||
{
|
||||
n = 3;
|
||||
arr = new double[n];
|
||||
arr[0] = source.Vx;
|
||||
arr[1] = source.Vy;
|
||||
arr[2] = source.Vz;
|
||||
}
|
||||
|
||||
public Vector(double[] source)
|
||||
{
|
||||
n = source.Length;
|
||||
arr = new double[source.Length];
|
||||
arr = (double[])source.Clone();
|
||||
}
|
||||
|
||||
public double[] ToArray()
|
||||
{
|
||||
return arr;
|
||||
}
|
||||
|
||||
public Vector3d ToVector3d()
|
||||
{
|
||||
return new Vector3d { Vx = arr[0], Vy = arr[1], Vz = arr[2] };
|
||||
}
|
||||
}
|
||||
}
|
||||
97
Geometry/Vector2d.cs
Normal file
97
Geometry/Vector2d.cs
Normal file
@@ -0,0 +1,97 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Math;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Vector2d
|
||||
{
|
||||
double[] arr = new double[2];
|
||||
|
||||
public double this[int i] { get => arr[i]; set => arr[i] = value; }
|
||||
public double Vx { get => arr[0]; set => arr[0] = value; }
|
||||
public double Vy { get => arr[1]; set => arr[1] = value; }
|
||||
public double Norma { get => Sqrt(Pow(Vx, 2) + Pow(Vy, 2)); }
|
||||
public double[] Unit { get => new double[] { Vx / Norma, Vy / Norma }; }
|
||||
|
||||
public Vector2d()
|
||||
{
|
||||
arr = new double[3];
|
||||
}
|
||||
|
||||
public Vector2d(double v1, double v2)
|
||||
{
|
||||
arr = new double[2];
|
||||
arr[0] = v1; arr[1] = v2;
|
||||
}
|
||||
|
||||
public Vector2d(Vector2d source)
|
||||
{
|
||||
arr = new double[3];
|
||||
arr = (double[])source.arr.Clone();
|
||||
}
|
||||
|
||||
public Vector2d(Point2d source)
|
||||
{
|
||||
arr = new double[2];
|
||||
arr[0] = source.X; arr[1] = source.Y;
|
||||
}
|
||||
|
||||
public Vector2d(Vector source)
|
||||
{
|
||||
arr = new double[2];
|
||||
if (source.N >= 2)
|
||||
{
|
||||
arr[0] = source[0]; arr[1] = source[1];
|
||||
}
|
||||
}
|
||||
|
||||
public Vector2d(double[] source)
|
||||
{
|
||||
arr = new double[2];
|
||||
if (source.Length >= 2)
|
||||
{
|
||||
arr[0] = source[0]; arr[1] = source[1];
|
||||
}
|
||||
}
|
||||
|
||||
public static double CosAngleBetVectors(Vector2d v1, Vector2d v2)
|
||||
{
|
||||
return (v1.Vx * v2.Vx + v1.Vy * v2.Vy) / (Sqrt(v1.Vx * v1.Vx + v1.Vy * v1.Vy) * Sqrt(v2.Vx * v2.Vx + v2.Vy * v2.Vy));
|
||||
}
|
||||
|
||||
public double[] ToArray()
|
||||
{
|
||||
return arr;
|
||||
}
|
||||
|
||||
public Vector ToVector()
|
||||
{
|
||||
return new Vector(arr);
|
||||
}
|
||||
|
||||
public static Vector3d operator ^(Vector2d v1, Vector2d v2)
|
||||
{
|
||||
Vector3d tempV1 = new Vector3d(v1); Vector3d tempV2 = new Vector3d(v2);
|
||||
return new Vector3d
|
||||
{
|
||||
Vx = tempV1.Vy * tempV2.Vz - tempV1.Vz * tempV2.Vy,
|
||||
Vy = tempV1.Vz * tempV2.Vx - tempV1.Vx * tempV2.Vz,
|
||||
Vz = tempV1.Vx * tempV2.Vy - tempV1.Vy * tempV2.Vx
|
||||
};
|
||||
}
|
||||
|
||||
public static Vector2d operator *(Vector2d v1, Vector2d v2)
|
||||
{
|
||||
return new Vector2d
|
||||
{
|
||||
Vx = v1.Vx * v2.Vx,
|
||||
Vy = v1.Vy * v2.Vy
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
107
Geometry/Vector3d.cs
Normal file
107
Geometry/Vector3d.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static System.Math;
|
||||
|
||||
namespace Geo
|
||||
{
|
||||
[Serializable]
|
||||
public class Vector3d : IVector
|
||||
{
|
||||
double[] arr;
|
||||
int n = 3;
|
||||
|
||||
public double this[int i] { get => arr[i]; set => arr[i] = value; }
|
||||
public double Vx { get => arr[0]; set => arr[0] = value; }
|
||||
public double Vy { get => arr[1]; set => arr[1] = value; }
|
||||
public double Vz { get => arr[2]; set => arr[2] = value; }
|
||||
public double Norma { get => Sqrt(Pow(Vx, 2) + Pow(Vy, 2) + Pow(Vz, 2)); }
|
||||
public double[] Unit { get => new double[] { Vx / Norma, Vy / Norma, Vz / Norma }; }
|
||||
public int N { get => n; }
|
||||
|
||||
public Vector3d()
|
||||
{
|
||||
arr = new double[3];
|
||||
}
|
||||
|
||||
public Vector3d(Vector3d source)
|
||||
{
|
||||
arr = new double[3];
|
||||
arr = (double[])source.arr.Clone();
|
||||
}
|
||||
|
||||
public Vector3d(Point3d source)
|
||||
{
|
||||
arr = new double[3];
|
||||
arr[0] = source.X; arr[1] = source.Y; arr[2] = source.Z;
|
||||
}
|
||||
|
||||
public Vector3d(Vector source)
|
||||
{
|
||||
arr = new double[3];
|
||||
if (source.N >= 3)
|
||||
{
|
||||
arr[0] = source[0]; arr[1] = source[1]; arr[2] = source[2];
|
||||
}
|
||||
}
|
||||
|
||||
public Vector3d(Vector2d source)
|
||||
{
|
||||
arr = new double[3];
|
||||
arr[0] = source.Vx;
|
||||
arr[1] = source.Vy;
|
||||
arr[2] = 0;
|
||||
}
|
||||
|
||||
public Vector3d(double[] source)
|
||||
{
|
||||
arr = new double[3];
|
||||
if (source.Length >= 3)
|
||||
{
|
||||
arr[0] = source[0]; arr[1] = source[1]; arr[2] = source[2];
|
||||
}
|
||||
}
|
||||
|
||||
public static double CosAngleBetVectors(Vector3d v1, Vector3d v2)
|
||||
{
|
||||
return (v1.Vx * v2.Vx + v1.Vy * v2.Vy + v1.Vz * v2.Vz) / (Sqrt(v1.Vx* v1.Vx + v1.Vy* v1.Vy+ v1.Vz * v1.Vz) * Sqrt(v2.Vx * v2.Vx + v2.Vy * v2.Vy + v2.Vz * v2.Vz));
|
||||
}
|
||||
|
||||
public double[] ToArray()
|
||||
{
|
||||
return arr;
|
||||
}
|
||||
|
||||
public Vector2d ToVector2d()
|
||||
{
|
||||
return new Vector2d() { Vx = Vx, Vy = Vy };
|
||||
}
|
||||
|
||||
public Vector ToVector()
|
||||
{
|
||||
return new Vector(arr);
|
||||
}
|
||||
|
||||
public static Vector3d operator ^(Vector3d v1, Vector3d v2)
|
||||
{
|
||||
return new Vector3d
|
||||
{
|
||||
Vx = v1.Vy * v2.Vz - v1.Vz * v2.Vy,
|
||||
Vy = v1.Vz * v2.Vx - v1.Vx * v2.Vz,
|
||||
Vz = v1.Vx * v2.Vy - v1.Vy * v2.Vx
|
||||
};
|
||||
}
|
||||
|
||||
public static Vector3d operator *(Vector3d v1, Vector3d v2)
|
||||
{
|
||||
return new Vector3d
|
||||
{
|
||||
Vx = v1.Vx * v2.Vx,
|
||||
Vy = v1.Vy * v2.Vy,
|
||||
Vz = v1.Vz * v2.Vz
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user