2010-03-23 14 views
9

Sto utilizzando il framework di route-me per lavorare con le posizioni. In questo codice il percorso tra due marker (punti) verrà disegnato come una linea.Triangolo di disegno/freccia su una linea con CGContext

La mia domanda: "Quale codice devo aggiungere se voglio aggiungere una freccia in mezzo (o superiore) della linea, in modo che punti la direzione"

Grazie



- (void)drawInContext:(CGContextRef)theContext 
{ 
    renderedScale = [contents metersPerPixel]; 

    float scale = 1.0f/[contents metersPerPixel]; 

    float scaledLineWidth = lineWidth; 
    if(!scaleLineWidth) { 
     scaledLineWidth *= renderedScale; 
    } 
    //NSLog(@"line width = %f, content scale = %f", scaledLineWidth, renderedScale); 

    CGContextScaleCTM(theContext, scale, scale); 

    CGContextBeginPath(theContext); 
    CGContextAddPath(theContext, path); 

    CGContextSetLineWidth(theContext, scaledLineWidth); 
    CGContextSetStrokeColorWithColor(theContext, [lineColor CGColor]); 
    CGContextSetFillColorWithColor(theContext, [fillColor CGColor]); 

    // according to Apple's documentation, DrawPath closes the path if it's a filled style, so a call to ClosePath isn't necessary 
    CGContextDrawPath(theContext, drawingMode); 
} 

+0

ho preso qualche tempo fa da http://www.codeguru.com/cpp/gm/gdi/article.php/c3683 Comunque thansk per le risposte Greetz – Pete

+0

Pete, può essere carino da parte tua contrassegnare comunque una risposta come accettata o postare la risposta come risposta e quindi accettarla. –

+0

@Pete perché non hai contrassegnato la risposta corretta (intendo quella di Friedhelm)? – yas375

risposta

5

Il disegno del triangolo/freccia attuale è facile una volta che hai due punti sul tuo percorso.

CGContextMoveToPoint(context , ax , ay); 
CGContextAddLineToPoint(context , bx , by); 
CGContextAddLineToPoint(context , cx , cy); 
CGContextClosePath(context); // for triangle 

Ottenere i punti è un po 'più complicato. Hai detto che il percorso era una linea, al contrario di una curva o una serie di curve. Questo lo rende più facile.

Utilizzare CGPathApply per selezionare due punti sul percorso. Probabilmente, questo è gli ultimi due punti, uno dei quali potrebbe essere kCGPathElementMoveToPoint e l'altro sarà kCGPathElementAddLineToPoint. Sia mx, my sia il primo punto e nx, ny sia il secondo, quindi la freccia punterà da m verso n.

Supponendo che si desideri la freccia sulla punta della linea, bx, da sopra sarà uguale nx, ny sulla linea. Scegliere un punto dx, dy tra mx, my e nx, ny per calcolare gli altri punti.

Ora calcolare ax, ay e cx, cy tale che siano su una linea con dx, dy ed equidistante dal percorso. Il seguente dovrebbe essere vicino, anche se probabilmente ho avuto alcuni segnali di sbagliato:

r = atan2(ny - my , nx - mx); 
bx = nx; 
by = ny; 
dx = bx + sin(r) * length; 
dy = by + cos(r) * length; 
r += M_PI_2; // perpendicular to path 
ax = dx + sin(r) * width; 
ay = dy + cos(r) * width; 
cx = dx - sin(r) * width; 
cy = dy - cos(r) * width; 

lunghezza è la distanza dalla punta della freccia alla base, e la larghezza è la distanza dal pozzo per le barbe, o mezzo di larghezza della testa della freccia.

Se path è una curva, invece di trovare mx, my come punto o spostamento precedente, sarà il punto di controllo finale della curva finale. Ogni punto di controllo si trova su una linea tangente alla curva e passa attraverso il punto adiacente.

2

Ho trovato questa domanda come ho avuto lo stesso. Ho preso esempio drawnonward di ed era così vicino ... Ma con un capovolgimento di cos e sin, sono stato in grado di farlo funzionare:

r = atan2(ny - my , nx - mx); 
r += M_PI; 
bx = nx; 
by = ny; 
dx = bx + cos(r) * length; 
dy = by + sin(r) * length; 
r += M_PI_2; // perpendicular to path 
ax = dx + cos(r) * width; 
ay = dy + sin(r) * width; 
cx = dx - cos(r) * width; 
cy = dy - sin(r) * width; 

Una volta che ho fatto, le mie frecce erano puntate esattamente il modo sbagliato . Così ho aggiunto quella seconda riga (r += M_PI;)

Grazie a drawonward!

20
- (void) drawLine: (CGContextRef) context from: (CGPoint) from to: (CGPoint) to 
{ 
    double slopy, cosy, siny; 
    // Arrow size 
    double length = 10.0; 
    double width = 5.0; 

    slopy = atan2((from.y - to.y), (from.x - to.x)); 
    cosy = cos(slopy); 
    siny = sin(slopy); 

    //draw a line between the 2 endpoint 
    CGContextMoveToPoint(context, from.x - length * cosy, from.y - length * siny); 
    CGContextAddLineToPoint(context, to.x + length * cosy, to.y + length * siny); 
    //paints a line along the current path 
    CGContextStrokePath(context); 

    //here is the tough part - actually drawing the arrows 
    //a total of 6 lines drawn to make the arrow shape 
    CGContextMoveToPoint(context, from.x, from.y); 
    CGContextAddLineToPoint(context, 
         from.x + (- length * cosy - (width/2.0 * siny)), 
         from.y + (- length * siny + (width/2.0 * cosy))); 
    CGContextAddLineToPoint(context, 
         from.x + (- length * cosy + (width/2.0 * siny)), 
         from.y - (width/2.0 * cosy + length * siny)); 
    CGContextClosePath(context); 
    CGContextStrokePath(context); 

    /*/-------------similarly the the other end-------------/*/ 
    CGContextMoveToPoint(context, to.x, to.y); 
    CGContextAddLineToPoint(context, 
         to.x + (length * cosy - (width/2.0 * siny)), 
         to.y + (length * siny + (width/2.0 * cosy))); 
    CGContextAddLineToPoint(context, 
         to.x + (length * cosy + width/2.0 * siny), 
         to.y - (width/2.0 * cosy - length * siny)); 
    CGContextClosePath(context); 
    CGContextStrokePath(context); 
}