根据DXF对鼓起值的说明(组代码42):
凸起(可选;默认值为0)。凸起是一个弧段所包含的角度的四分之一的切线,如果弧线从起始点顺时针走向终点,则为负角。凸起的0表示直线段,凸起的1表示半圆。
现在,我发现了这个关于计算凸起的资源,但是它适用于lisp编程。然而,它也在一定程度上指出:
多边形圆弧段的曲率是用一个称为凸起的量来定义的。这个单位测量的曲线偏离直线(和弦)连接两个顶点的分段。它被定义为弧形矢状面与两个顶点之间弦长的一半之比,这个比率等于两个多边形顶点之间所包含的弧角的四分之一的切线。 以这种方式,负凸起表示弧沿顺时针方向从第一个顶点到下一个顶点,正凸起描述了一个逆时针方向的弧。凸起的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方法,其中传递一个顶点索引和一个凸起因子。
有谁能告诉我如何把我发现的东西付诸行动,使我有正确的膨胀因素?
谢谢。
发布于 2017-04-06 14:21:23
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;
}
}https://stackoverflow.com/questions/43252483
复制相似问题