2017-04-06 66 views
1

折线对象根据用于BULGE值(组码42)的DXF指令:计算隆起因素的Bricscad的

凸出(可选;默认值为0)。凸出部分是圆弧段的夹角的四分之一的正切,如果圆弧从起点顺时针方向到终点,则该圆弧为 。 0的凸起表示 是直线段,并且1的凸起是半圆形。现在

,我发现这个resource有关计算凸起,但它是口齿不清编程。然而,在部分还指出:

折线圆弧段的曲率使用称为隆起的量 限定。该单位测量曲线与连接线段两个顶点的直线(和弦)的偏差。它定义为弧弧长度(versine)与两个顶点之间弦长 的一半的比值;该比率等于两个折线顶点之间的包括的弧角的四分之一的正切值 。

以这种方式,负凸起表示从第一顶点到下一个具有描绘逆时针方向的弧的正凸起的顺时针方向的弧。 A 0的凸出部分表示直线段,1的凸出部分是半圆形的 。

我写在C#中的例程Bricscad的,并试图创建一个凸起物Polyline。我快到了:

目前,这是我如何构建顶点。请注意,我正在考虑一个范围,然后在两侧以一定幅度抵消范围。在同一时间我拼接凸起值:

Polyline oPolyRect = new Polyline(); 
    oPolyRect.AddVertexAt(0, 
     new Point2d(extentsSelection3d.MinPoint.X - dMarginLeft, extentsSelection3d.MinPoint.Y), 0.0, 0.0, 0.0); 
    oPolyRect.AddVertexAt(1, 
     new Point2d(extentsSelection3d.MinPoint.X - dMarginLeft, extentsSelection3d.MaxPoint.Y), -0.5, 0.0, 0.0); 
    oPolyRect.AddVertexAt(2, 
     new Point2d(extentsSelection3d.MinPoint.X, extentsSelection3d.MaxPoint.Y + dMarginTop), 0.0, 0.0, 0.0); 
    oPolyRect.AddVertexAt(3, 
     new Point2d(extentsSelection3d.MaxPoint.X, extentsSelection3d.MaxPoint.Y + dMarginTop), -0.5, 0.0, 0.0); 
    oPolyRect.AddVertexAt(4, 
     new Point2d(extentsSelection3d.MaxPoint.X + dMarginRight, extentsSelection3d.MaxPoint.Y), 0.0, 0.0, 0.0); 
    oPolyRect.AddVertexAt(5, 
     new Point2d(extentsSelection3d.MaxPoint.X + dMarginRight, extentsSelection3d.MinPoint.Y), -0.5, 0.0, 0.0); 
    oPolyRect.AddVertexAt(6, 
     new Point2d(extentsSelection3d.MaxPoint.X, extentsSelection3d.MinPoint.Y - dMarginBottom), 0.0, 0.0, 0.0); 
    oPolyRect.AddVertexAt(7, 
     new Point2d(extentsSelection3d.MinPoint.X, extentsSelection3d.MinPoint.Y - dMarginBottom), -0.5, 0.0, 0.0); 
    oPolyRect.AddVertexAt(8, 
     new Point2d(extentsSelection3d.MinPoint.X - dMarginLeft, extentsSelection3d.MinPoint.Y), 0.0, 0.0, 0.0); 

原则上它工作。问题是膨胀计算。我从空气中挑选了-0.5,这不够好。

Polyline对象还暴露了一个SetBulgeAt方法,其中您传递一个顶点索引和一个凸出因子。

任何人都可以请告诉我如何把我发现的行为,让我有正确的凸起因素?

谢谢。

here

回答

0

一个很好的答案被BricsSys是好心提供给我。

我刚才复制的C#代码的伟大工程:

public static class Extensions 
{ 
        // Adds an arc (fillet) at each vertex, if able. 
        public static void FilletAll(this Polyline pline, double radius) 
    { 
     int i = pline.Closed ? 0 : 1; 
     for (int j = 0; j < pline.NumberOfVertices - i; j += 1 + pline.FilletAt(j, radius)) 
     { } 
    } 

    // Adds an arc (fillet) at the specified vertex. Returns 1 if the operation succeeded, 0 if it failed. 
    public static int FilletAt(this Polyline pline, int index, double radius) 
    { 
     int prev = index == 0 && pline.Closed ? pline.NumberOfVertices - 1 : index - 1; 

     if (pline.GetSegmentType(prev) != _AcDb.SegmentType.Line || 
      pline.GetSegmentType(index) != _AcDb.SegmentType.Line) 
      return 0; 

     LineSegment2d seg1 = pline.GetLineSegment2dAt(prev); 
     LineSegment2d seg2 = pline.GetLineSegment2dAt(index); 

     Vector2d vec1 = seg1.StartPoint - seg1.EndPoint; 
     Vector2d vec2 = seg2.EndPoint - seg2.StartPoint; 

     double angle = (Math.PI - vec1.GetAngleTo(vec2))/2.0; 
     double dist = radius * Math.Tan(angle); 
     if (dist > seg1.Length || dist > seg2.Length) 
      return 0; 

     Point2d pt1 = seg1.EndPoint + vec1.GetNormal() * dist; 
     Point2d pt2 = seg2.StartPoint + vec2.GetNormal() * dist; 

     double bulge = Math.Tan(angle/2.0); 
     if (Clockwise(seg1.StartPoint, seg1.EndPoint, seg2.EndPoint)) 
      bulge = -bulge; 

     pline.AddVertexAt(index, pt1, bulge, 0.0, 0.0); 
     pline.SetPointAt(index + 1, pt2); 

     return 1; 
    } 

        // Evaluates if the points are clockwise. 
        private static bool Clockwise(Point2d p1, Point2d p2, Point2d p3) 
    { 
     return ((p2.X - p1.X) * (p3.Y - p1.Y) - (p2.Y - p1.Y) * (p3.X - p1.X)) < 1e-8; 
    } 
}