我正在做一些核心图形,我想知道我如何知道一条线是否会在屏幕上显示它的某些部分。
让我们从 x-5, y3 到 x2, y-7 画一条线。如果它是 1 像素宽,则屏幕上不会显示任何内容。如果它是 15 像素宽,则会显示它的某些部分。
我该如何检查?
我正在做一些核心图形,我想知道我如何知道一条线是否会在屏幕上显示它的某些部分。
让我们从 x-5, y3 到 x2, y-7 画一条线。如果它是 1 像素宽,则屏幕上不会显示任何内容。如果它是 15 像素宽,则会显示它的某些部分。
我该如何检查?
如果您只有行,则可以使用以下功能。否则,我建议您遍历整个线条长度,并在特定距离内创建一个线条宽度大小的正方形,并检查它是否在您的视图内。一个例子:如果你有一条从 x0y0 到 x7y0 的线。你会去 x1y0 创建一个你的画线大小的正方形(在这个例子中是 15),看看它是否与你的屏幕重叠。接下来转到 x2y0 等等。优点是它甚至可以使用贝塞尔曲线(一点 wiki 信息如何贝塞尔就足够了)。
// 编辑:(做了一点贝塞尔检查功能,应该可以工作,但尚未测试)而且我认为在绘制之前检查每一行并不是更高效:
- (void)bezierWithStart:(CGPoint)start cp1:(CGPoint)cp1 cp2:(CGPoint)cp2 end:(CGPoint)end withWidth:(float)wid {
for (float i = 0.0; i<=1.0; i+=0.05) { // how many steps
CGPoint chk1 = CGPointMake(start.x+((cp1.x-start.x)*i), start.y+((cp1.y-start.y)*i));
CGPoint chk2 = CGPointMake(cp1.x+((cp2.x-cp1.x)*i), cp1.y+((cp2.y-cp1.y)*i));
CGPoint chk3 = CGPointMake(cp2.x+((end.x-cp2.x)*i), cp2.y+((end.y-cp2.y)*i));
CGPoint chk4 = CGPointMake(chk1.x+((chk2.x-chk1.x)*i), chk1.y+((chk2.y-chk1.y)*i));
CGPoint chk5 = CGPointMake(chk2.x+((chk3.x-chk2.x)*i), chk2.y+((chk3.y-chk2.y)*i));
CGPoint cPoint = CGPointMake(chk4.x+((chk5.x-chk4.x)*i), chk4.y+((chk5.y-chk4.y)*i));
CGRect drawLine = CGRectMake(cPoint.x-(wid/2), cPoint.y-(wid/2), wid, wid);
// check if rect is in view
}
}
// 编辑结束
但现在让我们进入简单的线函数:
- (void)testLine:(CGPoint)fp toSecond:(CGPoint)sp withWidth:(float)wid {
float xratio = sp.x - fp.x;
float yratio = sp.y - fp.y;
double a = sqrt(((wid*wid)*(xratio*xratio))/((yratio*yratio)+(xratio*xratio)));
a/=2; // because line width goes in both direction
double b = (yratio/xratio)*a;
if ((xratio<0.0 && yratio<0.0) || (xratio>0.0 && yratio>0.0))b*=-1;
CGPoint diffFrom1 = CGPointMake(fp.x+a, fp.y+b);
CGPoint diffTo1 = CGPointMake(sp.x+a, sp.y+b);
a*=-1;
b*=-1;
CGPoint diffFrom2 = CGPointMake(fp.x+a, fp.y+b);
CGPoint diffTo2 = CGPointMake(sp.x+a, sp.y+b);
}
你会得到4分。2 条线,一条在原始线的上方,一条在原始线的下方,是绘制宽度的一半。后面的计算是获取绘制方向以及与原始线的差异。但是对于那些想要进入它的人来说,这是我的预先计算: