完成基本的旋转和输出dxf文件

Signed-off-by: facat <facat@facat.com>
This commit is contained in:
facat 2021-06-09 23:03:28 +08:00
commit 53bc81b989
9 changed files with 393 additions and 0 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
cadlib
bin
MathNet.Numerics.4.15.0
obj
Properties

22
Program.cs Normal file
View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransmissionGraphic.Graphic;
using TransmissionGraphic.Type3D;
namespace TransmissionGraphic
{
class Program
{
static void Main(string[] args)
{
Canvas canvas = new Canvas();
canvas.init_canvas();
Line line = new Line(canvas,new TGVector3D(10, 20, 10), new TGVector3D(400, 25, 35), 0.32e-3, 400);
canvas.draw(line.curve());
canvas.save("abc.dxf");
}
}
}

View File

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{9A62FBFE-70BE-4CAD-A0D5-402024C8FB26}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>TransmissionGraphic</RootNamespace>
<AssemblyName>TransmissionGraphic</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
<FileAlignment>512</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="MathNet.Numerics">
<HintPath>MathNet.Numerics.4.15.0\lib\net40\MathNet.Numerics.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
<Reference Include="WW">
<HintPath>cadlib\WW.dll</HintPath>
</Reference>
<Reference Include="WW.Cad">
<HintPath>cadlib\WW.Cad.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="src\Graphic\Canvas.cs" />
<Compile Include="src\Graphic\Line.cs" />
<Compile Include="src\Transformation\Rotation.cs" />
<Compile Include="src\Transformation\Transformation.cs" />
<Compile Include="src\Type3D\Vector3D.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

3
app.config Normal file
View File

@ -0,0 +1,3 @@
<?xml version="1.0"?>
<configuration>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

47
src/Graphic/Canvas.cs Normal file
View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WW.Cad.Model;
using WW.Cad.Model.Entities;
using WW.Cad.IO;
using MathNet.Numerics.LinearAlgebra;
namespace TransmissionGraphic.Graphic
{
class Canvas
{
private DxfModel _model;
public Canvas()
{
this._model = null;
}
public void init_canvas()
{
DxfModel model = new DxfModel(DxfVersion.Dxf13);
this._model = model;
}
public void draw(Matrix<double> points)
{
DxfModel model=this._model;
DxfPolyline3D polyline = new DxfPolyline3D();
DxfVertex3D[] vertex = new DxfVertex3D[points.RowCount];
for (int foo = 0; foo < points.RowCount; foo++)
{
vertex[foo] = new DxfVertex3D(points.At(foo, 0), points.At(foo, 1), points.At(foo, 2));
}
polyline.Closed = false;
polyline.Vertices.AddRange(vertex);
model.Entities.Add(polyline);
}
public void save(string filePath)
{
DxfModel model = this._model;
DxfWriter.Write(filePath, model);
}
}
}

72
src/Graphic/Line.cs Normal file
View File

@ -0,0 +1,72 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransmissionGraphic.Type3D;
using MathNet.Numerics.LinearAlgebra;
using TransmissionGraphic.Transformation;
using MathNet.Numerics;
namespace TransmissionGraphic.Graphic
{
class Line
{
private TGVector3D _start_p;
private TGVector3D _end_p;
private double _tension_k;
private int _n_point;
private double _span;
private Matrix<double> _points;
private Rotation _rotation;
private Canvas _canvas;
public Line(Canvas canvas, TGVector3D start_p, TGVector3D end_p, double tension_k, int n_point)
{
this._start_p = start_p;
this._end_p = end_p;
this._tension_k = tension_k;
this._n_point = n_point;
this._span = 0;
this._points = null;
this._rotation = null;
this._canvas = canvas;
}
public Matrix<double> curve(bool draw = false)
{
if (this._points != null)
{
return this._points;
}
TGVector3D start_p = this._start_p;
TGVector3D end_p = this._end_p;
double tension_k = this._tension_k;
int n_point = this._n_point;
// 右手坐标系Z朝上
TGVector3D line = new TGVector3D(end_p.x, end_p.y, end_p.z) - new TGVector3D(start_p.x, start_p.y, start_p.z);
// 计算与X轴的角度
TGVector3D xy_project = new TGVector3D(line.x, line.y, line.z); // 投影到xy平面上
xy_project.z = 0;
double x_abs_angel = xy_project.angle_to(new TGVector3D(1, 0, 0));
double x_angel = x_abs_angel * Math.Sign(xy_project.y);
double height = end_p.z - start_p.z;
double span = xy_project.abs();
this._span = span;
Vector<double> span_l = Vector<double>.Build.DenseOfArray(Generate.LinearSpaced(n_point, 0, span)); // 档距
Vector<double> z_points = start_p.z + span_l * height / span - span_l.PointwiseMultiply(span - span_l)* tension_k / Math.Cos(Math.Atan(height / span));
double[,] p_points = new double[n_point, 3];
for (int foo = 0; foo < n_point; foo++)
{
p_points[foo, 0] = span_l[foo] + start_p.x;
p_points[foo, 1] = start_p.y;
p_points[foo, 2] = z_points[foo];
}
// 绕Z轴旋转
Rotation rotation = new Rotation(x_angel, new TGVector3D(start_p.x, start_p.y, start_p.z), new TGVector3D(start_p.x, start_p.y, start_p.z + 1));
this._rotation = rotation;
Matrix<double> points = rotation.rotate(Matrix<double>.Build.DenseOfArray(p_points));
return points;
}
}
}

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransmissionGraphic.Type3D;
using MathNet.Numerics.LinearAlgebra.Double;
using MathNet.Numerics.LinearAlgebra;
//using TransmissionGraphic.Transformation;
namespace TransmissionGraphic.Transformation
{
class Rotation
{
private Matrix<double> _r_transform;
public Rotation(double angel, TGVector3D axis_start, TGVector3D axis_end)
{
this._r_transform = Transformation.rotation_matrix(angel, axis_start, axis_end);
}
public Matrix<double> rotate(Matrix<double> point)
{
Matrix<double> r_transform = this._r_transform;
Matrix<double> onesMatrix=Matrix.Build.Dense(point.RowCount,1,1);
Matrix<double> expand_point = point.Append(onesMatrix);
Matrix<double> transformed_points = r_transform * expand_point.Transpose();
return Matrix.Build.DenseOfRows(transformed_points.EnumerateRows(0, transformed_points.RowCount-1)).Transpose();
}
}
}

View File

@ -0,0 +1,94 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TransmissionGraphic.Type3D;
using MathNet.Numerics.LinearAlgebra;
namespace TransmissionGraphic.Transformation
{
class Transformation
{
public static Matrix<double> create_rx(TGVector3D unit_axis)
{
double a = unit_axis.x;
double b = unit_axis.y;
double c = unit_axis.z;
double d = Math.Pow((b * b + c * c), 0.5);
Matrix<double> m = Matrix<double>.Build.DenseOfArray(new double[,]{
{1, 0, 0, 0},
{0, c / d, -b / d, 0},
{0, b / d, c / d, 0},
{0, 0, 0, 1}
});
return m;
}
public static Matrix<double> create_ry(TGVector3D unit_axis)
{
double a = unit_axis.x;
double b = unit_axis.y;
double c = unit_axis.z;
double d = Math.Pow((b * b + c * c), 0.5);
Matrix<double> m = Matrix<double>.Build.DenseOfArray(new double[,]{
{d, 0, -a, 0},
{0, 1, 0, 0},
{a, 0, d, 0},
{0, 0, 0, 1}
});
return m;
}
public static Matrix<double> create_rz(double angel)
{
Matrix<double> m = Matrix<double>.Build.DenseOfArray(new double[,]{
{Math.Cos(angel), -Math.Sin(angel), 0, 0},
{Math.Sin(angel), Math.Cos(angel), 0, 0},
{0, 0, 1, 0},
{0, 0, 0, 1}
});
return m;
}
public static Matrix<double> create_t(TGVector3D axis)
{
double x1, y1, z1;
x1 = axis.x;
y1 = axis.y;
z1 = axis.z;
Matrix<double> m = Matrix<double>.Build.DenseOfArray(new double[,]{
{1, 0, 0, -x1},
{0, 1, 0, -y1},
{0, 0, 1, -z1},
{0, 0, 0, 1}
});
return m;
}
public static Matrix<double> rotation_matrix(double angel, TGVector3D axis_start, TGVector3D axis_end)
{
TGVector3D axis = axis_end - axis_start;
TGVector3D unit_axis = axis / axis.abs();
Matrix<double> rz = create_rz(angel);
Matrix<double> rx = create_rx(unit_axis);
Matrix<double> ry = create_ry(unit_axis);
Matrix<double> t = create_t(axis_start);
Matrix<double> t_i = t.Inverse() ;
Matrix<double> rx_i = rx.Inverse() ;
Matrix<double> ry_i = ry.Inverse() ;
Matrix<double> r_transform = t_i * rx_i * ry_i * rz * ry * rx * t;
return r_transform;
}
public static Matrix<double> rotation(double angel, TGVector3D axis_start, TGVector3D axis_end, Matrix<double> points)
{
Rotation _rotation = new Rotation(angel, axis_start, axis_end);
return _rotation.rotate(points);
}
}
}

47
src/Type3D/Vector3D.cs Normal file
View File

@ -0,0 +1,47 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TransmissionGraphic.Type3D
{
public class TGVector3D
{
public double x;
public double y;
public double z;
public TGVector3D(double x, double y, double z)
{
this.x = x;
this.y = y;
this.z = z;
}
public static TGVector3D operator- (TGVector3D me, TGVector3D other)
{
return new TGVector3D(me.x - other.x, me.y - other.y, me.z - other.z);
}
public static TGVector3D operator /(TGVector3D me, double other)
{
return new TGVector3D(me.x / other, me.y / other, me.z / other);
}
public double abs()
{
return Math.Pow((this.x *this.x + this.y*this.y + this.z*this.z),.5);
}
// 计算两向量间夹角
public double angle_to(TGVector3D other)
{
return Math.Acos(
Math.Abs(this.x * other.x + this.y * other.y + this.z * other.z) / this.abs() / other.abs()
);
}
}
}