The following method returns the arrowheads ( bezierpath objects ).
See the return statement you will understand.
+ (NSArray *)bezierPathWithLineArrowHeadOfstartPoint:(NSPoint)startPoint endPoint:(NSPoint)endPoint startLineStyle:(INLineArrowStyle)lineTailStyle endLineStyle:(INLineArrowStyle)lineHeadStyle width:(float)lineWidth
{
double start_H_Left_r,start_V_Top_r,end_H_Right_r,end_V_Bottom_r;
long line_Width_l;
start_H_Left_r = startPoint.x;
start_V_Top_r = startPoint.y;
end_H_Right_r = endPoint.x;
end_V_Bottom_r = endPoint.y;
line_Width_l = lineWidth; //This method works best for lines widths <= 3
NSString *startingSide = [NSString string];
if ( start_H_Left_r <= end_H_Right_r )
startingSide = [NSString stringWithFormat:@”left”];
else
if ( start_H_Left_r >= end_H_Right_r )
startingSide = [NSString stringWithFormat:@”right”];
double slope;
slope = ( end_V_Bottom_r – start_V_Top_r )/((start_H_Left_r – end_H_Right_r ) + 0.1);
//sets the slope to a “high” number when the line is horizontal or vertical
if ( slope > 350 )
slope = -350;
else
if ( slope < -350 )
slope = 350;
// This sets the length of the arrow from the tip to the base.
double adjR,oppR,startingPointR,xStartingPointR = 0.0f,yStartingPointR = 0.0f;
// the length of the arrow is 8 pixels + the line width
startingPointR = 18 + line_Width_l;
adjR = sqrt( (pow(startingPointR,2))/pow((abs(slope) + 1),2) ); // deltaX
oppR = slope * adjR; // deltaY
// This adjusts the starting point for the base of the arrow so it is correctly oriented on the line.
if ( [startingSide isEqualToString: @”left”] ) {
xStartingPointR = adjR;
yStartingPointR = oppR;
} else
if ( [startingSide isEqualToString: @”right”] ) {
xStartingPointR = -adjR;
yStartingPointR = -oppR;
} else
NSLog(@”shouldn’t happen”);
// This calculates the base of the arrow
double lengthOfPerpendicularR,tangentLineLengthR;
tangentLineLengthR = 4 + line_Width_l;
lengthOfPerpendicularR = sqrt( (pow(tangentLineLengthR,2))/(4*(pow(slope,2) + 1)));
//This calculates the base of the arrow for the polygon
double pStart_H_Left_r,pStart_V_Top_r,pEnd_H_Right_r,pEnd_V_Bottom_r;
pStart_H_Left_r = end_H_Right_r – xStartingPointR – ( lengthOfPerpendicularR * slope );
pStart_V_Top_r = end_V_Bottom_r + yStartingPointR – ( lengthOfPerpendicularR );
pEnd_H_Right_r = end_H_Right_r – xStartingPointR + ( lengthOfPerpendicularR * slope );
pEnd_V_Bottom_r = end_V_Bottom_r + yStartingPointR + ( lengthOfPerpendicularR );
NSBezierPath *arrowHead,*arrowTail;
arrowHead = arrowTail = [NSBezierPath bezierPath];
[arrowHead moveToPoint:endPoint];
if ( lineHeadStyle == INArrowStyle ) {
[arrowHead lineToPoint:NSMakePoint(pStart_H_Left_r,pStart_V_Top_r)];
[arrowHead lineToPoint:NSMakePoint(pEnd_H_Right_r,pEnd_V_Bottom_r)];
[arrowHead lineToPoint:endPoint];
} else if ( lineHeadStyle == INCircleStyle ) {
[arrowHead appendBezierPathWithOvalInRect:NSMakeRect(endPoint.x-2.5f,endPoint.y-2.5f,5.0f,5.0f)];
} else if ( lineHeadStyle == INOpenArrowStyle ) {
[arrowHead lineToPoint:NSMakePoint(pStart_H_Left_r,pStart_V_Top_r)];
[arrowHead lineToPoint:endPoint];
[arrowHead lineToPoint:NSMakePoint(pEnd_H_Right_r,pEnd_V_Bottom_r)];
[arrowHead lineToPoint:endPoint];
} else if ( lineHeadStyle == INDiamondStyle ) {
NSPoint s1 = NSMakePoint(pStart_H_Left_r,pStart_V_Top_r);
NSPoint s2 = NSMakePoint(pEnd_H_Right_r,pEnd_V_Bottom_r);
float xV = s2.x-s1.x;
float xValue = s1.x+(xV/2.0f);
float yV = s2.y-s1.y;
float yValue = s1.y+(yV/2.0f);
float pointX = endPoint.x-((endPoint.x-xValue)*2);
float pointY = endPoint.y-((endPoint.y-yValue)*2);
[arrowHead lineToPoint:s1];
[arrowHead lineToPoint:NSMakePoint(pointX,pointY)];
[arrowHead lineToPoint:s2];
[arrowHead lineToPoint:endPoint];
} else if ( lineHeadStyle == INPointYArrowStyle ) {
NSPoint s1 = NSMakePoint(pStart_H_Left_r,pStart_V_Top_r);
NSPoint s2 = NSMakePoint(pEnd_H_Right_r,pEnd_V_Bottom_r);
float xV = s2.x-s1.x;
float xValue = s1.x+(xV/2.0f);
float yV = s2.y-s1.y;
float yValue = s1.y+(yV/2.0f);
float pointX = endPoint.x-((endPoint.x-xValue)/2);
float pointY = endPoint.y-((endPoint.y-yValue)/2);
[arrowHead lineToPoint:s1];
[arrowHead lineToPoint:NSMakePoint(pointX,pointY)];
[arrowHead lineToPoint:s2];
[arrowHead lineToPoint:endPoint];
}
[arrowTail moveToPoint:startPoint];
pStart_H_Left_r = start_H_Left_r + xStartingPointR + ( lengthOfPerpendicularR * slope );
pStart_V_Top_r = start_V_Top_r – yStartingPointR + ( lengthOfPerpendicularR );
pEnd_H_Right_r = start_H_Left_r + xStartingPointR – ( lengthOfPerpendicularR * slope );
pEnd_V_Bottom_r = start_V_Top_r – yStartingPointR – ( lengthOfPerpendicularR );
if ( lineTailStyle == INArrowStyle ) {
[arrowTail lineToPoint:NSMakePoint(pStart_H_Left_r,pStart_V_Top_r)];
[arrowTail lineToPoint:NSMakePoint(pEnd_H_Right_r,pEnd_V_Bottom_r)];
[arrowTail lineToPoint:startPoint];
} else if ( lineTailStyle == INCircleStyle ) {
[arrowTail appendBezierPathWithOvalInRect:NSMakeRect(startPoint.x-2.5f,startPoint.y-2.5f,5.0f,5.0f)];
} else if ( lineTailStyle == INOpenArrowStyle ) {
[arrowTail lineToPoint:NSMakePoint(pStart_H_Left_r,pStart_V_Top_r)];
[arrowTail lineToPoint:startPoint];
[arrowTail lineToPoint:NSMakePoint(pEnd_H_Right_r,pEnd_V_Bottom_r)];
[arrowTail lineToPoint:startPoint];
} else if ( lineTailStyle == INDiamondStyle ) {
NSPoint s1 = NSMakePoint(pStart_H_Left_r,pStart_V_Top_r);
NSPoint s2 = NSMakePoint(pEnd_H_Right_r,pEnd_V_Bottom_r);
float xV = s2.x-s1.x;
float xValue = s1.x+(xV/2.0f);
float yV = s2.y-s1.y;
float yValue = s1.y+(yV/2.0f);
float pointX = startPoint.x-((startPoint.x-xValue)*2);
float pointY = startPoint.y-((startPoint.y-yValue)*2);
[arrowTail lineToPoint:s1];
[arrowTail lineToPoint:NSMakePoint(pointX,pointY)];
[arrowTail lineToPoint:s2];
[arrowTail lineToPoint:startPoint];
} else if ( lineTailStyle == INPointYArrowStyle ) {
NSPoint s1 = NSMakePoint(pStart_H_Left_r,pStart_V_Top_r);
NSPoint s2 = NSMakePoint(pEnd_H_Right_r,pEnd_V_Bottom_r);
float xV = s2.x-s1.x;
float xValue = s1.x+(xV/2.0f);
float yV = s2.y-s1.y;
float yValue = s1.y+(yV/2.0f);
float pointX = startPoint.x-((startPoint.x-xValue)/2);
float pointY = startPoint.y-((startPoint.y-yValue)/2);
[arrowTail lineToPoint:s1];
[arrowTail lineToPoint:NSMakePoint(pointX,pointY)];
[arrowTail lineToPoint:s2];
[arrowTail lineToPoint:startPoint];
}
return [NSArray arrayWithObjects:arrowHead,arrowTail,nil];
}
technorati tags:cocoa, nsbezierpath, line, arrowhead, method
Blogged with Flock
March 14, 2009 at 12:36 pm
It’s the first time I comment here and I must say that you share us genuine, and quality information for bloggers! Good job.
p.s. You have a very good template . Where did you find it?
January 22, 2011 at 10:20 am
you might have an ideal blog here! would you like to make some invite posts on my blog?