使用CGContext(工作)将NSString数组显示为圆,但没有角度?

时间:2014-11-26 18:13:51

标签: ios objective-c rotation nsstring

我有一个函数,用NSStrings作为一个圆圈绘制NSArray。它到目前为止工作正常。从给定的起始角度到给定的结束角度显示阵列标记。 据我了解此代码的工作方式,它首先将字符串置于法线角度。在此之后,弦绕着中心以给定半径旋转希望的角度。结果是,弦线位于圆周围的正确位置,旋转时带有一定的角度。

看起来像这样:

enter image description here

正如你所看到的,越来越难以阅读颠倒的数字。所以如果琴弦的旋转角度为0°会更好。有没有办法防止弦的最终角度或在它们放置后旋转它们? 感谢任何tipps。

这是实际在中间围绕圆圈绘制字符串的函数:

-(void)createScale{

scaleText =@[@"-5",@"-4",@"-3",@"-2",@"-1",@"0",@"1",@"2",@"3",@"4",@"5"];
// Start drawing

CGContextRef context = UIGraphicsGetCurrentContext();

// Retrieve the center and set a radius

CGFloat r = _center.x;

// Start by adjusting the context origin
// This affects all subsequent operations
CGContextTranslateCTM(context, _center.x, _center.y);

// Iterate through the alphabet
for (int i = 0; i < self.scaleText.count; i++)
{
    UIFont* font =[UIFont fontWithName:@"Helvetica" size:20.0];
    // Retrieve the letter and measure its display size
    NSString *letter =
    [self.scaleText objectAtIndex:i];
    //CGSize letterSize =[letter sizeWithAttributes:@{NSFontAttributeName:@"Helvetica"}];
    CGSize size = [letter sizeWithAttributes:@{NSFontAttributeName:font}];
    CGFloat theta;
    // Calculate the current angular offset
    if(_endAngle-_startAngle<0){
        theta = i * (DEG2RAD(_startAngle-_endAngle)/ (float) (self.scaleText.count+1))-DEG2RAD(360-_startAngle);
    }else{
        theta = i * (DEG2RAD(_endAngle-_startAngle)/ (float) (self.scaleText.count-1))-DEG2RAD(360-_startAngle);}

    // Encapsulate each stage of the drawing
    CGContextSaveGState(context);

    // Rotate the context

    CGContextRotateCTM(context, theta);

    // Translate up to the edge of the radius and move left by
    // half the letter width. The height translation is negative
    // as this drawing sequence uses the UIKit coordinate system.
    // Transformations that move up go to lower y values.

    CGContextTranslateCTM(context, -size.width / 2, -r);
    UIColor* fontColor=[UIColor blackColor];

    //colors lowest, or highest number in string
    if(i==0 && ((NSString*)[self.scaleText objectAtIndex:i]).intValue<0){
        fontColor=[UIColor redColor];
    }
    if(i==self.scaleText.count-1&& ((NSString*)[self.scaleText objectAtIndex:self.scaleText.count-1]).intValue>0){
        fontColor=[UIColor greenColor];
    }

    // Draw the letter and pop the transform state

    [letter drawAtPoint:CGPointMake(0, 0)
         withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName : fontColor }];
    CGContextRestoreGState(context);
}

}

### ADDED ###

正如Duncan C建议的那样,我放弃了CGContext的东西并用Trig放置了文本。

-(void)createScale{

// Start drawing

CGContextRef context = UIGraphicsGetCurrentContext();
// Retrieve the center
CGContextTranslateCTM(context, _center.x, _center.y);

// Iterate through the array
for (int i = 0; i < self.scaleText.count; i++)
{
    UIFont* font =[UIFont fontWithName:@"Helvetica" size:20.0];
    // Retrieve the letter and measure its display size
    NSString *letter =[self.scaleText objectAtIndex:i];

    UIColor* fontColor=[UIColor blackColor];
    //colors lowest, or highest number in string
    if(i==0 && ((NSString*)[self.scaleText objectAtIndex:self.scaleText.count-1]).intValue<=0){
        fontColor=[UIColor redColor];
    }
    if(i==self.scaleText.count-1&& ((NSString*)[self.scaleText objectAtIndex:self.scaleText.count-1]).intValue>0){
        fontColor=[UIColor greenColor];
    }

    CGFloat theta;
    // Calculate the current angular offset

    //when overturn
    if(_endAngle-_startAngle<0){
        theta = i * (DEG2RAD(_startAngle-_endAngle)/ (float) (self.scaleText.count+1))+DEG2RAD(_startAngle);
        //normal case
    }else{
        theta = i * (DEG2RAD(_endAngle-_startAngle)/ (float) (self.scaleText.count-1))+DEG2RAD(_startAngle);}

    CGFloat y = round(cosf(theta) * _radiusScale) ;
    CGFloat x = round(sinf(theta) * _radiusScale) ;
    // Draw the letter and pop the transform state
    [letter drawAtPoint:CGPointMake(x, -y) withAttributes:@{NSFontAttributeName:font,NSForegroundColorAttributeName : fontColor }];
}

}

现在琴弦确实以零°0°的角度找到了它们的位置,但我确实得到了一个奇怪的偏移,我不知道它可能来自哪里。在过去的几个小时里我一直在努力解决这个问题,但仍然无法解决这个问题。

enter image description here

1 个答案:

答案 0 :(得分:2)

根本不要旋转琴弦。相反,使用trig(正弦和余弦)计算每个字符串的中心位置。

以下是如何使用trig来查找要绘制的数字的中心点的方法:

记住trig函数的助记符:SOA CAH TOA

sine = opposite over adjacent
cosine= adjacent over hypotenuse
tangent = opposite over adjacent

绘制一个以图表原点为中心的圆圈。在第一个象限中放置一个直角三角形,一个角位于圆的中心,另一个角位于0到45度之间的圆圈处。从该点向下放置一条垂直线到x轴。我们在函数中使用的角度是圆心的角度。斜边是从圆心到边缘的直线。相邻侧是三角形(x)的水平腿。与角度相对的一侧是三角形的垂直腿(y)。

sine(angle) = x/radius
x = radius * sine(angle)

cos(angle) = y/radius
y = radius * cos(angle)

现在您有一个公式,用于根据角度和所需的圆半径计算数字的中心点。使用该公式将数字放在圆圈周围。

我有一个project on github(链接),使用这种方法绘制一个钟面。