ios - 圆内圆环,动态调整大小

标签 ios cocoa dynamic geometry drawrect

全部。 抱歉,如果这个问题已经被问过并得到回答,我在搜索时找不到这个具体问题。

我正在尝试创建一个圆类,该类可以动态地在一个圆内创建一个圆环,但我对它背后的三角函数有疑问。这个想法是为旋转电话创建一个图像,但我希望能够将此类重用于其他类似的图像(用于加载图像的圆圈等)。

从我的 View Controller 中,我调用 CustomCircleView,它会很好地创建基圆(我使用这个圆作为背景颜色,以便我可以单独调整它的色调)。 然后我调用我的 DialView 类,它也可以很好地创建基圆,但我的切口没有出现在我期望的位置。

我想要的是有 12 个均匀分布的圆圈,并使用 EOFill 让它们透明。 EOFill 工作正常,所有内容都显示没有错误,但我的圆圈没有显示在我期望的位置;很可能,这意味着我的数学有问题。

相关代码如下:

- (void)drawRect:(CGRect)rect
{
    int inset = 2;  // space between cutouts and edge of dial
    int circleDiameter = self.bounds.size.width - inset * 2;
    float circleRadius = circleDiameter / 2;
    float holeDiameter = circleDiameter * 0.15;  // wrong size; is there a formula for this?
    float holeRadius = holeDiameter / 2;
    int holePadding = 2;  // space between cutouts
    float hypotenuse = circleRadius - holeRadius - holePadding;
    float dispX;
    float dispY;

    // Set context.
    CGContextRef context = UIGraphicsGetCurrentContext();

    // Set line stroke parameters.
    CGContextSetLineWidth(context, 2.0);
    CGContextSetStrokeColorWithColor(context, [UIColor colorWithHue:0.6 saturation:1.0 brightness:1.0 alpha:1.0].CGColor);
    CGContextSetFillColorWithColor(context, self.dialColor.CGColor);

    // main dial circle; this will remain visible
    CGRect ellipse = CGRectMake(self.bounds.origin.x + inset, self.bounds.origin.y + inset, circleDiameter, circleDiameter);
    CGContextAddEllipseInRect(context, ellipse);

    // grid for debugging; remove once circles line up properly
    CGContextMoveToPoint(context, 0, 0);
    CGContextAddLineToPoint(context, self.bounds.size.width, self.bounds.size.height);
    CGContextMoveToPoint(context, 0, self.bounds.size.height);
    CGContextAddLineToPoint(context, self.bounds.size.width, 0);
    CGContextStrokePath(context);

    // circle spacing based on 12 circles
    // hole diameter should be proportional to that of dial diameter

    // 1
    dispX = (self.bounds.size.width / 2)  + (cosf(45) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) - (sinf(45) * hypotenuse) - (holeRadius);
    CGRect hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 2
    dispX = (self.bounds.size.width / 2)  + (cosf(75) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) - (sinf(75) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 3
    dispX = (self.bounds.size.width / 2)  - (cosf(75) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) - (sinf(75) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 4
    dispX = (self.bounds.size.width / 2)  - (cosf(45) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) - (sinf(45) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 5
    dispX = (self.bounds.size.width / 2)  - (cosf(15) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) - (sinf(15) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 6
    dispX = (self.bounds.size.width / 2)  - (cosf(15) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) + (sinf(15) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 7
    dispX = (self.bounds.size.width / 2)  - (cosf(45) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) + (sinf(45) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 8
    dispX = (self.bounds.size.width / 2)  - (cosf(75) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) + (sinf(75) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 9
    dispX = (self.bounds.size.width / 2)  + (cosf(75) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) + (sinf(75) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);

    // 0
    dispX = (self.bounds.size.width / 2)  + (cosf(45) * hypotenuse) - (holeRadius);
    dispY = (self.bounds.size.height / 2) + (sinf(45) * hypotenuse) - (holeRadius);
    hole = CGRectMake(dispX, dispY, holeDiameter, holeDiameter);
    CGContextAddEllipseInRect(context, hole);


    CGContextEOFillPath(context);
}

最佳答案

想通了。 我在三角函数中使用度数,而不是弧度。

如果其他人正在尝试做与我相同的事情,请研究斯坦纳链以帮助找到您的半径比。

关于ios - 圆内圆环,动态调整大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5901895/

相关文章:

ios - 当键是 NSNumber 时,我可以调用 nsdictionary 的 valueForKeyPath 吗?

c++ - 使用 ARC 在 C 函数中取消引用 self,引用作为 intptr_t 传递

c++ - 动态转换指向引用的指针和指向指针的引用

javascript - 如何在 jQuery Ajax 中发送动态键和值?

iOS : perform task in background when app is force quit by user

objective-c - 需要 CCRenderTexture 来渲染更快的 ios

objective-c - 将对象从数组添加到字典

objective-c - 找不到 Cocoapods 框架

macos - 在 OS X 登录窗口启动应用程序

c# - 在 .NET 4.0 (C#) 中动态实现接口(interface)