在QQ群为风吹桥动改写优化多段线的倒角程序,
原代码使用DB库的曲线并用纯数学计算方式
-
-
- ///
- /// 通过一个顶点将多义线倒圆角,本程序不支持多义线起点和终点处倒圆角
- ///
- /// 多义线对象
- /// 顶点索引号
- /// 圆弧半径
- public static void FilletatVertex(Polyline polyline, int vertexIndex, double radius)
- {
- Database db = HostApplicationServices.WorkingDatabase;//获取数据库
- Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;//获取editor对象
- using (Transaction trans = db.TransactionManager.StartTransaction())//开始事务
- {
- try
- {
- //判断顶点索引号是否属于多义线;
- if (vertexIndex = polyline.NumberOfVertices)
- {
- ed.WriteMessage("\n顶点无效。");
- return;
- }
- else if ((polyline.GetBulgeAt(vertexIndex - 1) != 0) && (polyline.GetBulgeAt(vertexIndex) != 0))
- {
- ed.WriteMessage("\n顶点两侧不是直线。");
- return;
- }
- else
- {
- Point2d pnt = polyline.GetPoint2dAt(vertexIndex);
- Vector2d vec1 = polyline.GetPoint2dAt(vertexIndex - 1) - pnt;//由顶点与前一个顶点组成的向量
- Vector2d vec2 = polyline.GetPoint2dAt(vertexIndex + 1) - pnt;//由顶点与后一个顶点组成的向量
- double angle = vec1.GetAngleTo(vec2);//获得角点两侧线段间的角度变化
- ed.WriteMessage(angle.ToString());
- ed.WriteMessage("\n" + vec1.Length.ToString());
- ed.WriteMessage("\n" + (radius / Math.Tan(angle / 2)).ToString());
- ed.WriteMessage("\n" + vec2.Length.ToString());
- ed.WriteMessage("\n" + (radius / Math.Tan(angle / 2)).ToString());
- if ((vec1.Length
- /// 为优化多段线倒角
- ///
- /// 优化多段线
- /// 顶点索引号
- /// 倒角半径
- /// 倒角类型
- public static void ChamferAt(this Polyline polyline, int index, double radius, bool isFillet)
- {
- if (index polyline.NumberOfVertices - 2)
- throw new System.Exception("错误的索引号");
- if (polyline.GetSegmentType(index - 1) != SegmentType.Line || polyline.GetSegmentType(index) != SegmentType.Line)
- throw new System.Exception("非直线段不能倒角");
- //获取当前索引号的前后两段直线,并组合为Ge复合曲线
- Curve3d[] c3ds =
- new Curve3d[]
- {
- polyline.GetLineSegmentAt(index - 1),
- polyline.GetLineSegmentAt(index)
- };
- var cc3d = new CompositeCurve3d(c3ds);
- //试倒直角
- //子曲线的个数有三种情况:
- //1、=3时倒角方向正确
- //2、=2时倒角方向相反
- //3、=0或为直线时失败
- c3ds =
- cc3d.GetTrimmedOffset
- (
- radius,
- Vector3d.ZAxis,
- OffsetCurveExtensionType.Chamfer
- );
- if (c3ds.Length > 0 && c3ds[0] is CompositeCurve3d)
- {
- var newcc3d = c3ds[0] as CompositeCurve3d;
- c3ds = newcc3d.GetCurves();
- if (c3ds.Length == 3)
- {
- c3ds =
- cc3d.GetTrimmedOffset
- (
- -radius,
- Vector3d.ZAxis,
- OffsetCurveExtensionType.Chamfer
- );
- if (c3ds.Length == 0 || c3ds[0] is LineSegment3d)
- {
- throw new System.Exception("倒角半径过大");
- }
- }
- else if (c3ds.Length == 2)
- {
- radius = -radius;
- }
- }
- else
- {
- throw new System.Exception("倒角半径过大");
- }
- //GetTrimmedOffset会生成倒角+偏移,故先反方向倒角,再倒回
- c3ds =
- cc3d.GetTrimmedOffset
- (
- -radius,
- Vector3d.ZAxis,
- OffsetCurveExtensionType.Extend
- );
- OffsetCurveExtensionType type =
- isFillet ?
- OffsetCurveExtensionType.Fillet : OffsetCurveExtensionType.Chamfer;
- c3ds =
- c3ds[0].GetTrimmedOffset
- (
- radius,
- Vector3d.ZAxis,
- type
- );
- //将结果Ge曲线转为Db曲线,并将相关的数值反映到原曲线
|