将Autocad的图形填充(Hatch)转化为三角形
目前在研究通过DirectX 或者OpenGL来显示Dwg图纸,一些基本的功能已经完成,但是对于图形填充遇到了一些问题。
DirectX中基本的元素只有三角形,但是Autocad的图形填充可以是任意几何图形,所以我们需要将Autocad的图形填充转换为三角形。
虽然有很多图形计算理论,但是以前没做这一块,决定还是找现有的类库来完成这个过程。
由于Hatch的定义为若干个Loop之间的运算,目前看来是Xor 计算,所以,第一步为确定图块计算的类库。考虑到图块计算基于点线,而结果也是点线,暂时排除了C# 默认的System.Drawing里面的Geometry和WPF 里面的Path类库。而是采用了Clipper(http://angusj.com/delphi/clipper.php#features)。
参考代码如下:
Clipper cpr = new Clipper();
int idx = 0;
foreach (var subitem in item.SubItems) {
var path = new Path();
foreach (var p in subitem.Points) {
path.Add(new IntPoint(p.X, p.Y));
}
var txt = GetPointsText(path);
if (idx == 0)
{
cpr.AddPath(path, PolyType.ptSubject, true);
idx++;
}
else {
cpr.AddPath(path, PolyType.ptClip, true);
}
}
,cpr.Execute(ClipType.ctXor, shapes, PolyFillType.pftNonZero, PolyFillType.pftNonZero);
这里得到的结果shapes是若干个图形,其中第一个是图形是外轮廓,其他是内部的空洞,所以建立了2个三角形几何,一个是图形,一个是内部孔洞。
为了简化计算,图形使用Hatch自己的颜色绘制,而空洞采用背景色绘制。
idx = 0;
C2DPolygon hull = null;
bool isHole = false;
foreach (var shape in shapes) {
List<C2DPoint> pts = new List<C2DPoint>();
foreach (var p in shape) {
pts.Add(new C2DPoint(p.X, p.Y));
}
C2DPolygon plyg = new C2DPolygon(pts,true); //获取到几何对象
if (idx == 0)
{
hull = plyg;
isHole = false;
}
else {
isHole = hull.Contains(plyg);
}
plyg.CreateConvexSubAreas();//将当前对象拆分为多个凸角结合图形
subareas = new List<C2DPolygon>();
plyg.GetConvexSubAreas(subareas);//得到拆分后的几何图形。
foreach (var area in subareas)
{
c2dpoints.Clear();
area.GetPointsCopy(c2dpoints);
for (int i = 2; i < c2dpoints.Count; i++)
{
Point3D[] triangle = new Point3D[3];
triangle[0] = new Point3D(c2dpoints[0].x, c2dpoints[0].y, 0);
triangle[1] = new Point3D(c2dpoints[i - 1].x, c2dpoints[i - 1].y, 0);
triangle[2] = new Point3D(c2dpoints[i].x, c2dpoints[i].y, 0);
if (!isHole)
{
triangles.Add(triangle);
}
else {
holes.Add(triangle);
}
}
}
idx++;
}
在获取三角形的时候,我们用到了另外一个组件:GeoLib(http://www.geolib.co.uk/)
关键代码如下:
C2DPolygon plyg = new C2DPolygon(pts,true); //获取到几何对象
plyg.CreateConvexSubAreas();//将当前对象拆分为多个凸角结合图形
plyg.GetConvexSubAreas(subareas);//得到拆分后的几何图形。
得到凸角几何对象后,就可以很轻松的将结果拆分为三角形。