Graphics - How may I know if a line is visible onscreen taking account its width
I'm doing some 开发者_如何学运维core graphics, and I wonder how I may know if a line will have some parts of it visible on screen.
Let's take a line going from x-5, y3 to x2, y-7. If it's 1 pixel wide, nothing will be displayed onscreen. If it's 15 pixels wide, some parts of it will be displayed.
How may I check that ?
If you have lines only you can work with the function below. Otherwise I would recommend to go through the whole length of your line and create in a specific distance an square of the line width size and check if it is inside your view. An example: If you have a line from x0y0 to x7y0. You would go to x1y0 create a square of your draw line size (in this example 15) and see if this overlaps your screen. Next go to x2y0 and so on. The advantage is it will even work with bezier curves (a little wiki information how bezier work will be enough).
// EDIT: (made a little bezier check function, should work, but haven't tested) And I don't think its more performance efficient to check each line before drawing:
- (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
}
}
// EDIT end
But now lets go to the simple line function:
- (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);
}
you will get 4 points. 2 lines, one above and one below the original line, half the size of your draw width. The calculation behind is to get the draw direction and for that the difference to the original line. But for those who want to get into it, heres my pre calculation:
精彩评论