2012-01-03 86 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)。

相关问题