所以我有一个由n点组成的任意线(参见图1所示的例子)
我想围绕这条线绘制一个轮廓(见图2),所以我需要计算周围多边形的点。
我开始在线上进行扩张,但这不起作用 - 见图3
有关如何执行此操作的任何建议?
我怀疑计算每个线段的法线用于平移下面的新线和在当前位置上方的新线,然后将每个新线延伸到无穷大并将这些点定义为交叉点?
答案 0 :(得分:5)
首先复制每一行两次,每边一次,距离每条原始线的宽度的一半。这为您提供了图像中的绿线。然后你需要按顺序(编号)访问它们并处理松散的目的。
如果线条不符合(2-3,6-7和12-13),则添加线条连接(蓝色)。线连接可以是斜面连接(2-3),只需连接点,或斜接连接,通过扩展直到它们相遇(6-7)或通过制作曲线来圆形连接。
当线条相遇时,只需取交点(蓝点)。
在行结束时,您需要添加端盖(也是蓝色)。端盖可以是对接盖(8-9),通过连接点,突出盖(1-16),在连接它们之前稍微延伸线,或圆帽(未显示)。
最终结果是一个多边形(或路径,如果它包含圆形连接),然后你可以描边或填充。
答案 1 :(得分:3)
我想出了一种计算直线轮廓点的方法。对于原始线的每个点,您必须为轮廓计算2个点:
上面的颜色对应this image。
我已经在C中编写了这个函数,但是我使用了Accelerate Framework,所以它不是很容易阅读。您可以找到源代码here和运行演示here的视频。
答案 2 :(得分:0)
在渲染之前创建所有行。
当你这样做时,它们应该重叠,如下所示:
我所画的那些,显然是那些会被修剪掉的,可以显示轮廓。
答案 3 :(得分:0)
如果您有线段的点,您可以轻松地为每个线段创建两条平行线,并计算它们与下一条线相交的连接点(如果它们是线(而不是线段))。该网站应该为您提供计算超快交叉点所需的所有:
答案 4 :(得分:0)
以下是我在Objective-C中的一些代码(即使它有时有问题,我不知道为什么,让我知道它是怎么回事......):
最后,它按所需顺序添加每个点以制作多边形
- (hOzPolygon2D *) convertToPolygonWithWidth:(double) polyWidth
{
double shift = polyWidth / 2.;
NSMutableArray *tempEdgesRight = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *tempEdgesLeft = [[[NSMutableArray alloc] init] autorelease];
NSMutableArray *tempPolyPoints = [[[NSMutableArray alloc] init] autorelease];
// Move your points on the right by half the desired width
// My edges are already computed in a NSArray* called edges,
// but you can use pairs of vectors and adapt all this
for (hOzEdge2D *edge in edges) {
hOzVector2 v = hOzVector2([[edge pointB] x] - [[edge pointA] x], [[edge pointB] y] - [[edge pointA] y]);
double mag = sqrt (v.x * v.x + v.y * v.y);
v.x = v.x / mag;
v.y = v.y / mag;
double temp = v.x;
v.x = v.y;
v.y = -temp;
hOzPoint2D *newPointA = [[hOzPoint2D alloc] init];
[newPointA setX:([[edge pointA] x] + v.x * shift)];
[newPointA setY:([[edge pointA] y] + v.y * shift)];
hOzPoint2D *newPointB = [[hOzPoint2D alloc] init];
[newPointB setX:([[edge pointB] x] + v.x * shift)];
[newPointB setY:([[edge pointB] y] + v.y * shift)];
[tempEdgesRight addObject:[hOzEdge2D edge2DWithPointA:newPointA pointB:newPointB]];
}
// With the same polyline, move on the left
for (int j = [edges count] - 1; j >= 0; j--) {
hOzVector2 v = hOzVector2([[[edges objectAtIndex:j] pointB] x] - [[[edges objectAtIndex:j] pointA] x], [[[edges objectAtIndex:j] pointB] y] - [[[edges objectAtIndex:j] pointA] y]);
double mag = sqrt (v.x * v.x + v.y * v.y);
v.x = v.x / mag;
v.y = v.y / mag;
double temp = v.x;
v.x = v.y;
v.y = -temp;
hOzPoint2D *newPointA = [[hOzPoint2D alloc] init];
[newPointA setX:([[[edges objectAtIndex:j] pointB] x] - v.x * shift)];
[newPointA setY:([[[edges objectAtIndex:j] pointB] y] - v.y * shift)];
hOzPoint2D *newPointB = [[hOzPoint2D alloc] init];
[newPointB setX:([[[edges objectAtIndex:j] pointA] x] - v.x * shift)];
[newPointB setY:([[[edges objectAtIndex:j] pointA] y] - v.y * shift)];
[tempEdgesLeft addObject:[hOzEdge2D edge2DWithPointA:newPointA pointB:newPointB]];
}
// Add the static points and the intersection points to a points array that will define your polygon
[tempPolyPoints addObject:[[tempEdgesRight objectAtIndex:0] pointA]]; // The first point of the right array
for (int k = 0; k < [tempEdgesRight count] - 1; k++) {
// For this function, see the link below in the answer
hOzPoint2D *inter = [[tempEdgesRight objectAtIndex:k] getIntersectionWithStraight:[tempEdgesRight objectAtIndex:k+1]];
if (inter == nil) { // if the edges are parallel, we insert a known point
[tempPolyPoints addObject:[[tempEdgesRight objectAtIndex:k] pointB]];
} else {
[tempPolyPoints addObject:inter];
}
}
[tempPolyPoints addObject:[[tempEdgesRight lastObject] pointB]]; // The last point of the right array
[tempPolyPoints addObject:[[tempEdgesLeft objectAtIndex:0] pointA]];
// Then the left array, same thing
for (int k = 0; k < [tempEdgesLeft count] - 1; k++) {
hOzPoint2D *inter = [[tempEdgesLeft objectAtIndex:k] getIntersectionWithStraight:[tempEdgesLeft objectAtIndex:k+1]];
if (inter == nil) {
[tempPolyPoints addObject:[[tempEdgesLeft objectAtIndex:k] pointB]];
} else {
[tempPolyPoints addObject:inter];
}
}
[tempPolyPoints addObject:[[tempEdgesLeft lastObject] pointB]];
// Create your polygon with this new ordered points array.
hOzPolygon2D *poly = [hOzPolygon2D polygon2DWithArrayOfPoints:tempPolyPoints];
return poly;
}
以下是交叉点的一些解释,使用C代码:http://alienryderflex.com/intersect/