2010-03-23 26 views
9

bir hat üzerinde ok Ben yerleri ile çalışmak için rota-beni çerçevesini kullanıyorum. Bu kodda iki işaretçi (nokta) arasındaki yol bir çizgi olarak çizilecektir.Çizim üçgen/CGContext

Sorum:

Teşekkür



- (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

Ben http://www.codeguru.com/cpp/gm/gdi/article.php/c3683 tarafından bir süre önce var neyse cevaplar Selamlamak – Pete

+0

Pete için thansk, bu senin için çok iyi olabilir Yine de kabul edilen bir cevabı işaretleyin veya cevabınızı bir cevap olarak gönderin ve sonra bunu kabul edin. –

+0

@Pete neden doğru cevabı işaretlemediniz (Friedhelm'in)? – yas375

cevap

5

"Bunun yönünü işaret böylece hattın ortasında (veya üst) 'de bir ok eklemek istiyorsanız ne eklemelisiniz kodu" Yolunuzda iki noktaya sahip olduğunuzda gerçek üçgen/ok çizimi kolaydır. puan almak

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

biraz daha karmaşıktır. Yolun bir eğri veya bir dizi eğriye karşılık bir çizgi olduğunu söylediniz. Bu daha kolay hale getirir.

Kullanım CGPathApply yolu üzerinde iki noktayı seçmek. Muhtemelen, bu son iki nokta, biri kCGPathElementMoveToPoint ve diğeri kCGPathElementAddLineToPoint olacaktır. Bırak mx, ilk nokta ve nx, ny ikinci, bu yüzden ok m'den n'ye doğru işaret edecektir.

yukarıdan yaparak, çizgi, bx ucundaki ok istiyorum varsayarsak olacak eşit nx, on line ny. Diğer noktaları hesaplamak için bir nokta dx, mx, my ve nx, ny arasında bir boya seçin.

Şimdi ax, ay ve cx, onlar dx, dy ve yol eşit uzaklıkta olan bir hat üzerinde olacak şekilde cy hesaplayın. Muhtemelen yanlış bazı işaretler var, ancak şu, yakın olmalıdır:

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; 

Uzunluk tabanına okun ucu mesafedir ve genişlik tellerle şaft mesafedir, ya da yarım genişlik ok başı. yol bir eğri ise

ardından yerine mx bulma, benim daha önceki nokta veya hareket olarak, bu son eğrinin son kontrol noktası olacaktır. Her kontrol noktası, eğriye teğet olan ve bitişik noktadan geçen bir hat üzerindedir.

2

Ben de aynı soruyu buldum. Ben örneğini drawnonward aldı ve o kadar yakın oldu ... Ama cos ve günahın bir lanetleme ile, işe almak başardı:

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; 

benim oklar tam yanlış bir şekilde işaret edildi yaptım kez . Bu yüzden ikinci hat (r += M_PI;)

sayesinde drawnonward gitmek sözlerine ekledi!

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); 
}