2012-01-03 58 views
16

您可以使用下面的代碼繪製使用Quartz弧:使用CGContextAddArcToPoint()繪製圓弧時,(x1,y1)和(x2,y2)是什麼意思?

CGContextMoveToPoint(context2, x, y); 
CGContextAddArcToPoint(context2, x1, y1, x2, y2, r); 

在這些功能中,(x,y)的出發點和r是圓弧半徑但什麼是(x1,y1)(x2,y2)

+0

請問http://developer.apple.com/library/IOs/#documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html不能解釋它嗎?真正的問題,如果你不這樣做,這是一個有點數學。 – jrturton 2012-01-03 08:58:27

回答

10

http://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html#//apple_ref/c/func/CGContextAddArcToPoint

x1:所述的x值,在用戶空間中的座標,對於第一切線的終點。第一條切線從當前點繪製到(x1,y1)。

y1:用戶空間座標中第一條切線終點的y值。第一條切線從當前點繪製到(x1,y1)。

x2:用戶空間座標中的x值,用於第二條切線的終點。第二條切線從(x1,y1)到(x2,y2)。

y2:用戶空間座標中第二條切線終點的y值。第二條切線從(x1,y1)到(x2,y2)。

+2

James Snook的答案有一個更清晰的解釋。 – OutOnAWeekend 2014-05-03 02:28:36

6

這是我剛建的解決了這個代碼,從中央的圓的角度接近它,報關單和樣本值:

CGPoint arcCenter = CGPointMake(30,20); 
float arcLengthRad = M_PI_4; // Whatever, the full span of the arc in radians 
float radius = 10; 
float arcCenterRad = M_PI_2; // the angle of the center of the arc, in radians 

float arcP1hyp = 1/cos(arcLengthRad/2) * radius; 
float arcP1x = arcCenter.x + cosf(arcCenterRad)*arcP1hyp; 
float arcP1y = arcCenter.y + sinf(arcCenterRad)*arcP1hyp; 
float arcP2tx = arcCenter.x + cosf(arcCenterRad+(arcLengthRad/2))*radius; 
float arcP2ty = arcCenter.y + sinf(arcCenterRad+(arcLengthRad/2))*radius; 
float arcP2x = (arcP1x - arcP2tx)*-1 + arcP2tx; 
float arcP2y = (arcP1y - arcP2ty)*-1 + arcP2ty; 
CGContextAddArcToPoint(context, 
         arcP1x, 
         arcP1y, 
         arcP2x, 
         arcP2y, 
         radius); 

所以上面的代碼應該產生一個小的,45度角弧在圓的頂部。


被修改: 響應於評論接收,上面列出的超簡潔代碼如下所示,與評論和包裹在一個方法(加一個小的調整時arcP2計算)

/* 
EOTContext:addArcWithCenter:arcLength:radius:arcMiddlePointAngle: 

Use this method for building a circle with breaks at certain points, 
for example to use other CGContext methods to draw notches in the 
circle, or protruding points like gear teeth. 

This method builds up the values to use in CGContextAddArcToPoint(), 
which are the x and y coordinates of two points. First added to 
the current point in context, form two lines that are the tangents of 
the entry and exit angles of the arc. 

This method's arguments define the length of the arc in radians, and 
the position of start and end using the angle centerpoint of the arc. 
This is useful when drawing a certain defined amount of gear teeth, 
rotating around the circle. 

It is beyond this method's scope to maintain or calculate the 
centerpoint relative to an arbitrary current point in the context, because this 
is primarily used for drawing a gear/notch circle. 
*/ 
-(void)EOTContext:(CGContext*)context 
addArcWithCenter:(CGPoint)arcCenter 
arcLength:(CGFloat)arcLengthRad 
radius:(CGFloat)radius 
arcMiddlePointAngle:(CGFloat)arcCenterRad { 



    /* 
    Calculate the hypotenuse of the larger, outer circle where the 
    points of the tangent lines would rest upon (imagine wrapping 
    the drawn circle in a bounding regular convex polygon of tangent 
    lines, then wrap that polygon in an outer circle) 
    */ 
    float arcP1hyp = 1/cos(arcLengthRad/2) * radius; 

    // Build first tangent point 
    CGPoint arcP1 = (CGPoint){ 
     arcCenter.x + cosf(arcCenterRad)*arcP1hyp, 
     arcCenter.y + sinf(arcCenterRad)*arcP1hyp 
    }; 

    // Build the final endpoint of the arc 
    CGPoint arcP2final = (CGPoint){ 
     arcCenter.x + cosf(arcCenterRad+(arcLengthRad/2))*radius, 
     arcCenter.y + sinf(arcCenterRad+(arcLengthRad/2))*radius 
    }; 

    // Build second tangent point using the first tangent point and the final point of the arc. 
    // This point is resting on the bounding outer circle like arcP1 is. 
    // This would also work using the final point itself, using the simple assignment of arcP2 = arcP2final; 
    // or of course simply omitting arcP2 altogether. 
    CGPoint arcP2 = (CGPoint){ 
     (arcP2final.x - arcP1.x) + arcP2final.x, 
     (arcP2final.y - arcP1.y) + arcP2final.y 
    }; 

    // The following adds an arc of a circle to the current path, using a radius and tangent points. 
    CGContextAddArcToPoint(context, 
          arcP1.x, 
          arcP1.y, 
          arcP2.x, 
          arcP2.y, 
          radius); 
} 
+0

你能解釋一下你是如何做計算的? – Moxy 2013-02-14 18:28:03

+0

當我計算出這個數字時,我已經在筆記本上寫了一些數學的細節,但是在我完成所有工作之後扔掉了紙張!但它不是太具有挑戰性。只知道使用我的特定代碼的上下文很重要。對於繪製帶凹口的圓形,將其繪製爲一系列圓弧,或繪製一個帶齒突出的齒輪很有用,但缺口或齒的繪製超出了上述代碼的範圍。 – 2013-02-15 00:07:55

+0

對代碼添加了註釋。太糟糕了,這個問題已經被回答了。 – 2013-02-15 01:30:57

65

AddArcToPoint是這樣工作的:

ArcToPoint Diagram

其中P1是路徑當前所在的點,r是給予函數的radius,紅線是addArcToPoint將添加到當前路徑的行。它不會繼續到第二點x2, y2;它會停在弧線的盡頭。我的博客文章here

+0

顯然我無法在這裏添加圖像,因爲我沒有足夠高的代表。抱歉。 – 2013-09-25 19:20:52

+0

不錯的形象。我嵌入這一個,但你應該能夠做你的下一個(除非我記得正確的權限)。 +1 – 2013-09-25 20:01:13

+0

優秀的解釋。 Quartz2D指南中的插圖沒有太大意義,這更清晰。 – OutOnAWeekend 2014-05-03 02:27:09

0

我簡要描述了它的蘋果文檔。

http://developer.apple.com/library/ios/documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html#//apple_ref/c/func/CGContextAddArcToPoint

X1:所述的x值,在用戶空間中的座標,對於第一切線的終點。第一條切線從當前點繪製到(x1,y1)。

y1:用戶空間座標中第一條切線終點的y值。第一條切線從當前點繪製到(x1,y1)。

x2:用戶空間座標中的x值,用於第二條切線的終點。第二條切線從(x1,y1)到(x2,y2)。

y2:用戶空間座標中的y值,用於第二條切線的終點。第二條切線從(x1,y1)到(x2,y2)。

相關問題