2012-01-03 14 views
16

Bạn có thể sử dụng đoạn mã sau để vẽ một vòng cung bằng thạch anh:Khi vẽ một vòng cung bằng cách sử dụng CGContextAddArcToPoint(), những gì (x1, y1) và (x2, y2) có nghĩa là gì?

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

Trong các chức năng này, (x,y) là điểm khởi đầu và r là bán kính vòng cung nhưng những gì (x1,y1)(x2,y2)?

+0

http://developer.apple.com/library/IOs/#documentation/GraphicsImaging/Reference/CGContext/Reference/reference.html không giải thích được? Câu hỏi chính xác, nó là một chút toán nặng nếu bạn không vào đó. – jrturton

Trả lời

10

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

x1: x có giá trị, trong tọa độ không gian sử dụng, cho các điểm cuối của đường tiếp tuyến đầu tiên. Đường tiếp tuyến đầu tiên được vẽ từ điểm hiện tại tới (x1, y1).

y1: Giá trị y, trong tọa độ không gian người dùng, cho điểm kết thúc của đường tiếp tuyến đầu tiên. Đường tiếp tuyến đầu tiên được vẽ từ điểm hiện tại tới (x1, y1).

x2: Giá trị x, trong tọa độ không gian người dùng, cho điểm kết thúc của đường tiếp tuyến thứ hai. Đường tiếp tuyến thứ hai được vẽ từ (x1, y1) đến (x2, y2).

y2: Giá trị y, trong tọa độ không gian người dùng, cho điểm cuối của dòng tiếp tuyến thứ hai. Đường tiếp tuyến thứ hai được vẽ từ (x1, y1) đến (x2, y2).

+2

Câu trả lời dưới đây của James Snook có một giải thích rõ ràng hơn nhiều. – OutOnAWeekend

6

Đây là mã tôi chỉ xây dựng để giải quyết việc này, tiếp cận nó từ góc độ tâm-of-vòng tròn, với tờ khai và các giá trị mẫu:

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

Vì vậy, các mã trên nên tạo ra một góc nhỏ, 45 độ vòng cung ở đầu vòng tròn.


được sửa đổi: Để đáp lại bình luận nhận được, mã siêu ngắn gọn liệt kê ở trên được hiển thị dưới đây, với ý kiến ​​và được bọc trong một phương pháp (cộng với một điều chỉnh nhỏ để tính toán 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

Bạn có thể giải thích cách bạn đã tính toán không? – Moxy

+0

Tôi đã có chi tiết cụ thể về toán học được viết trên một ghi chú khi tôi tính toán điều này, nhưng đã ném giấy ra sau khi tôi đã có tất cả làm việc! Nhưng nó không quá khó khăn. Chỉ cần biết bối cảnh sử dụng mã cụ thể của tôi là rất quan trọng. Nó hữu ích cho việc vẽ một vòng tròn với các rãnh, bằng cách vẽ nó như một loạt các vòng cung, hoặc vẽ một bánh răng, với hàm răng nhô ra, nhưng vết khía hoặc răng vẽ nằm ngoài phạm vi của đoạn mã trên. –

+0

Đã thêm nhận xét vào mã. Quá xấu câu hỏi đã được trả lời. –

65

AddArcToPoint làm việc như thế này:

ArcToPoint Diagram

trong đó P1 là điểm mà đường dẫn hiện tại đang ở, rradius được gán cho hàm và đường màu đỏ là dòng mà addArcToPoint sẽ thêm vào đường dẫn hiện tại. Nó sẽ không tiếp tục đến điểm thứ hai tại x2, y2; nó sẽ dừng lại ở cuối cung.

Tôi có một bài đăng trên blog về số này here.

+0

Rõ ràng tôi không thể thêm hình ảnh ở đây bản thân mình vì tôi không có đại diện đủ cao. Lấy làm tiếc. –

+0

Hình ảnh đẹp. Tôi đã nhúng cái này nhưng bạn sẽ có thể làm cái tiếp theo (trừ khi tôi nhớ chính xác quyền). +1 –

+0

Giải thích tuyệt vời. Hình minh họa trong hướng dẫn Quartz2D không có ý nghĩa gì nhiều, điều này rõ ràng hơn rất nhiều. – OutOnAWeekend

0

Tôi tài liệu về táo được mô tả ngắn gọn.

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

x1: x có giá trị, trong tọa độ không gian sử dụng, cho các điểm cuối của đường tiếp tuyến đầu tiên. Đường tiếp tuyến đầu tiên được vẽ từ điểm hiện tại tới (x1, y1).

y1: Giá trị y, trong tọa độ không gian người dùng, cho điểm kết thúc của đường tiếp tuyến đầu tiên. Đường tiếp tuyến đầu tiên được vẽ từ điểm hiện tại tới (x1, y1).

x2: Giá trị x, trong tọa độ không gian người dùng, cho điểm kết thúc của đường tiếp tuyến thứ hai. Đường tiếp tuyến thứ hai được vẽ từ (x1, y1) đến (x2, y2).

y2: Giá trị y, trong tọa độ không gian của người dùng, cho điểm kết thúc của đường tiếp tuyến thứ hai. Đường tiếp tuyến thứ hai được vẽ từ (x1, y1) đến (x2, y2).

Các vấn đề liên quan