介绍
开源项目出处(两个模块):
链接1:https://github.com/Scrawk/CGALDotNet/tree/master?tab=readme-ov-file
链接2:https://github.com/Scrawk/CGALDotNetGeometry
该项目提供了编译的、封装相关接口后的CGAL库,可供C#直接调用,无需自行编译CGAL。可根据需要封装更多接口。
快速开始
为了快速创建示例,直接使用编译好的dll:
- 下载编译好的CGAL的dll、封装的CGAL调用接口的dll:链接3:https://github.com/Scrawk/CGALDotNet/tree/master/Binaries,其框架版本为.net core3.1。
共包含5个dll:
- CGALDotNet.dll (对CGAL的C#封装接口,源码位于上文链接1)
- CGALDotNetGeometry.dll (对CGAL的C#封装接口,源码位于上文链接2)
- CGALWrapper.dll (CGAL的编译结果,源码位于上文链接1)
- gmp.dll (其他第三方库)
- mpfr-6.dll (其他第三方库)
- 创建框架版本为.net core3.1的控制台项目。
- 测试代码(判断三点是否共线):
using CGALDotNet;
using CGALDotNetGeometry.Numerics;
using System;
namespace CTestCore31
{
public class Program
{
static void Main(string[] args)
{
var p1 = new Point2d(1, 0);
var p2 = new Point2d(2, 0);
var p3 = new Point2d(3, 0);
var p4 = new Point2d(3, 1);
var isCollinear = CGALGlobal.Collinear(p1, p2, p3);
Console.WriteLine(isCollinear);//True
var isCollinear2 = CGALGlobal.Collinear(p1, p2, p4);
Console.WriteLine(isCollinear2);//False
Console.ReadLine();
}
}
}
更多示例
更多示例请参考上文链接1中的子目录:https://github.com/Scrawk/CGALDotNet/tree/master/CGALDotNetTest
下面列出一些示例。
矢量
两个矢量之间的角度
var t2 = new Vector2d(1, 1);
var u2 = new Vector2d(1, 0);
var v2 = new Vector2d(0, 1);
var w2 = new Vector2d(-1, 1);
Assert.AreEqual(CGALGlobal.Angle(t2, u2), ANGLE.ACUTE);//锐角
Assert.AreEqual(CGALGlobal.Angle(u2, v2), ANGLE.RIGHT);//直角
Assert.AreEqual(CGALGlobal.Angle(w2, u2), ANGLE.OBTUSE);//钝角
点
计算三个点的重心
var p = new Point2d(0, 0);
var q = new Point2d(1, 0);
var r = new Point2d(1, 1);
var bc = CGALGlobal.Barycenter(p, q, r);
bc.Round(2);
Assert.AreEqual(0.67, bc.x);
Assert.AreEqual(0.33, bc.y);
线
计算两点的垂直平分线
var p = new Point3d(1, 0, 0);
var q = new Point3d(0, 1, 0);
Assert.AreEqual(CGALGlobal.Bisector(p, q), new Line2d(2, -2, 0));//2x -2y + 0 = 0 => y = x
多边形
创建简单凸多边形
var points = new Point2d[]
{
new Point2d(0, 0),
new Point2d(5, 0),
new Point2d(5, 5),
new Point2d(0, 5)
};
var poly = new Polygon2<EEK>(points);
Assert.AreEqual(4, poly.Count);//点数
Assert.IsTrue(poly.IsSimple);//简单多边形
Assert.IsTrue(poly.IsCounterClockWise);//逆时针的点顺序
Assert.IsTrue(poly.Orientation == ORIENTATION.POSITIVE);//正负方向
Assert.IsTrue(poly.ClockDir == CLOCK_DIR.COUNTER_CLOCKWISE);//时针方向
Assert.IsTrue(poly.FindIfConvex());//凸多边形
创建简单凹多边形
var points = new Point2d[]
{
new Point2d(0,0),
new Point2d(5.1,0),
new Point2d(1,1),
new Point2d(0.5,6)
};
var poly = new Polygon2<EEK>(points);
Assert.AreEqual(4, poly.Count);
Assert.IsTrue(poly.IsSimple);
Assert.IsTrue(poly.IsCounterClockWise);
Assert.IsTrue(poly.Orientation == ORIENTATION.POSITIVE);
Assert.IsTrue(poly.ClockDir == CLOCK_DIR.COUNTER_CLOCKWISE);
Assert.IsFalse(poly.FindIfConvex());
创建非简单多边形
多边形存在自相交情况。
public void CreateNonSimplePolygon()
{
var points = new Point2d[]
{
new Point2d(0, 0),
new Point2d(8, 4),
new Point2d(8, 0),
new Point2d(0, 4),
};
var poly = new Polygon2<EEK>(points);
Assert.AreEqual(4, poly.Count);
Assert.IsFalse(poly.IsSimple);
Assert.IsTrue(poly.IsDegenerate);
Assert.IsTrue(poly.Orientation == ORIENTATION.ZERO);
Assert.IsTrue(poly.ClockDir == CLOCK_DIR.ZERO);
}
判断多边形包含点
var points = new Point2d[]
{
new Point2d(0, 0),
new Point2d(5, 0),
new Point2d(5, 5),
new Point2d(0, 5)
};
var poly = new Polygon2<EEK>(points);
var p1 = new Point2d(0, 0);
var p2 = new Point2d(2, 2);
var p3 = new Point2d(6, 0);
Assert.IsTrue(poly.ContainsPoint(p1));
Assert.IsTrue(poly.ContainsPoint(p2));
Assert.IsFalse(poly.ContainsPoint(p3));
创建简单带洞多边形
var points = new Point2d[]
{
new Point2d(0, 0),
new Point2d(5, 0),
new Point2d(5, 5),
new Point2d(0, 5)
};
var holePoints = new Point2d[]
{
new Point2d(1, 1),
new Point2d(2, 1),
new Point2d(3, 3),
new Point2d(1, 2)
};//洞的点坐标序列必须是逆时针的
var poly = new PolygonWithHoles2<EIK>(points);
var holePoly = new Polygon2<EIK>(holePoints);
poly.AddHole(holePoly);
var area = poly.FindArea(POLYGON_ELEMENT.BOUNDARY);//计算不含洞的面积
var area2 = poly.FindArea(POLYGON_ELEMENT.HOLE);//计算洞的面积
Assert.IsTrue(area == 25);
Assert.IsTrue(area2 == 2);
对CGAL的支持情况
CGALDotNet和CGALDotNetGeometry并未提供CGAL所有的对象和功能接口,所实现的接口参考https://github.com/Scrawk/CGALDotNet/tree/master?tab=readme-ov-file,翻译如下:
-
基础
- 数字类型
- 特征矩阵
- CGAL对象
- CGAL全局函数
- Unity扩展
-
几何
- 数值
- 图形
- 对象
- 相交
-
多边形
- 多边形对象
- 带洞多边形对象
- 多边形布尔运算
- 多边形Minkowski(闵可夫斯基和)
- 多边形偏移
- 多边形简化
- 多边形可视性
- 多边形分割
-
三角剖分(Triangulation)
- 三角剖分2D
- 三角剖分3D
-
排列(Arrangements)
- 排列2D
- 扫描线2D
-
多面体(Polyhedra)
- 多面体网格
- 网格处理