根据BULGE值的 DXF 说明(组代码42):
凸出(可选;默认为0)。凸起是四分之一的正切 弧段的夹角,如果弧线走,则为负 从起点到终点的顺时针方向。凸起为0表示 直线段,1的凸起是半圆形。
现在,我发现这个resource有关计算凸起的信息,但它适用于 lisp 编程。但是,它还部分说明:
使用数量定义折线弧段的曲率 被称为凸起。该单位测量曲线与曲线的偏差 连接段的两个顶点的直线(弦)。它是 定义为弧矢(常数)与长度的一半之比 两个顶点之间的和弦;这个比例等于 两者之间包含的弧角的四分之一的正切 折线顶点。
通过这种方式,负凸起表示 弧沿着从第一个顶点到下一个顶点的顺时针方向, 具有描述逆时针方向弧的正凸起。一个 凸起0表示直线段,凸起1表示a 半圆。
我正在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
方法,您可以在其中传递顶点索引和凸出因子。
任何人都可以告诉我如何将我发现的东西付诸实践,以便我有正确的膨胀因素吗?
谢谢。
答案 0 :(得分:0)
BricsSys向我提供了一个很好的答案:
看here。
我只复制了效果很好的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;
}
}