1

I would like to draw an arrow on the top of a line. I know the coordinates of the startPoint and endPoint, and I also know the angle and the length for the arrow.

My logic is :

  1. calculate slope angle between start point and end point
  2. calculate the position of the arrow points

I'm using the following formula:

CGFloat endX = cos(angleOfArrowPoint-slopeAngle) * distance + point.x;
CGFloat endY = sin(angleOfArrowPoint-slopeAngle) * distance + point.y;

What am I doing wrong?

Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
Mihai Popa
  • 892
  • 1
  • 8
  • 25
  • Since in the title of your question you wrote "the math", may I suggest you to have a look at the Affine Transformations, in particular at Rotations and Translations? If they are available in your programming environment, and if you can use them, you will be able to write code without the need of "raw" formulae but at an higher abstraction level. – Alessandro Jacopson Nov 16 '13 at 15:15
  • How is this not working? Can you describe what the code you included is producing? And how is that different from what you were expecting? Pics would be best. EDIT: just noticed how old this question is - are you still having trouble with this? If you fixed it yourself, you should post what you did as an answer and accept it. – GeneralMike Feb 28 '14 at 19:38
  • Have you looked at [this answer](http://stackoverflow.com/a/13559449/77567)? It may be simpler than your approach. – rob mayoff Feb 28 '14 at 19:47
  • posible problems: 1. check if your cos,sin angles needs radians or degrees, 2. one endpoint of arrow is -angle and second is +angle of course. 3.have you used atan2 ? for angle of line detection !!! clasical atan does not work on full 4 quadrant space !!! – Spektre Mar 03 '14 at 14:40
  • Rather than figure out your math, allow me to point you at [this answer](http://stackoverflow.com/a/13559449/77567), which you might find helpful. – rob mayoff May 26 '14 at 05:55

1 Answers1

0

Here is a method that I use to draw line with an arrow at either end, which shows you the math of drawing an arrow on a line. It should be easy to modify these method to your specific needs.

-(void)drawDoubleArrowLineInContext:(CGContextRef)inContext fromPoint:(CGPoint)inFromPoint toPoint:(CGPoint)inToPoint {

    CGContextSetLineWidth(inContext, 1.0 );
    CGContextSetStrokeColorWithColor( inContext, [UIColor blackColor].CGColor  );
    CGContextSetFillColorWithColor( inContext, [UIColor blackColor].CGColor );

    CGContextBeginPath( inContext );
    CGContextMoveToPoint( inContext, inFromPoint.x, inFromPoint.y );
    CGContextAddLineToPoint( inContext, inToPoint.x, inToPoint.y );
    CGContextClosePath( inContext );
    CGContextDrawPath( inContext, kCGPathStroke );

    [self drawArrowInContext:inContext atPoint:inFromPoint pointFrom:inToPoint];
    [self drawArrowInContext:inContext atPoint:inToPoint pointFrom:inFromPoint];
}

-(void)drawArrowInContext:(CGContextRef)inContext atPoint:(CGPoint)inTipPoint pointFrom:(CGPoint)inFromPoint {
    const CGFloat kArrowHeight = 15;
    const CGFloat kArrowBaseHalfWidth = 5;

    double arrowAngle = atan2( (inFromPoint.y - inTipPoint.y), (inFromPoint.x - inTipPoint.x ) );

    CGContextBeginPath( inContext );
    CGContextMoveToPoint( inContext, inTipPoint.x, inTipPoint.y );
    CGContextAddLineToPoint( inContext, (inTipPoint.x + kArrowHeight*cos(arrowAngle)) - kArrowBaseHalfWidth*sin(arrowAngle),
                                        (inTipPoint.y + kArrowHeight*sin(arrowAngle)) + kArrowBaseHalfWidth*cos(arrowAngle));
    CGContextAddLineToPoint( inContext, (inTipPoint.x + kArrowHeight*cos(arrowAngle)) + kArrowBaseHalfWidth*sin(arrowAngle),
                                        (inTipPoint.y + kArrowHeight*sin(arrowAngle)) - kArrowBaseHalfWidth*cos(arrowAngle));
    CGContextAddLineToPoint( inContext, inTipPoint.x, inTipPoint.y );
    CGContextClosePath( inContext );

    CGContextDrawPath( inContext, kCGPathFillStroke );
}
kamprath
  • 2,220
  • 1
  • 23
  • 28