我有一个函数,用NSStrings作为一个圆圈绘制NSArray。它到目前为止工作正常。从给定的起始角度到给定的结束角度显示阵列标记。 据我了解此代码的工作方式,它首先将字符串置于法线角度。在此之后,弦绕着中心以给定半径旋转希望的角度。结果是,弦线位于圆周围的正确位置,旋转时带有一定的角度。
看起来像这样:
正如你所看到的,越来越难以阅读颠倒的数字。所以如果琴弦的旋转角度为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°的角度找到了它们的位置,但我确实得到了一个奇怪的偏移,我不知道它可能来自哪里。在过去的几个小时里我一直在努力解决这个问题,但仍然无法解决这个问题。
答案 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(链接),使用这种方法绘制一个钟面。