如何使用Quartz Core画星星?
我正在尝试改编Apple提供的示例,以便以编程方式在线绘制星星,代码如下:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, aSize);
for (NSUInteger i=0; i<stars; i++)
{
CGContextSetFillColorWithColor(context, aColor);
CGContextSetStrokeColorWithColor(context, aColor);
float w = item.size.width;
double r = w / 2;
double theta = 2 * M_PI * (2.0 / 5.0); // 144 degrees
CGContextMoveToPoint(context, 0, r);
for (NSUInteger k=1; k<5; k++)
{
float x = r * sin(k * theta);
float y = r * cos(k * theta);
CGContextAddLineToPoint(context, x, y);
}
CGContextClosePath(context);
CGContextFillPath(context);
}
上面的代码绘制了一个完美的星星,但是1.显示颠倒了2.是黑色且没有边框。我想要实现的是在同一条线上并以给定的样式绘制许多星星。我知道我实际上在同一位置绘制了同一条路径 5 次,并且我必须以某种方式垂直翻转上下文,但经过几次测试后我放弃了! (我缺乏必要的数学和几何技能:P)...你能帮我吗?
更新:
好的,感谢CocoaFu,这是我重构和工作的绘图实用程序:
- (void)drawStars:(NSUInteger)count inContext:(CGContextRef)context;
{
// constants
const float w = self.itemSize.width;
const float r = w/2;
const double theta = 2 * M_PI * (2.0 / 5.0);
const float flip = -1.0f; // flip vertically (default star representation)
// drawing center for the star
float xCenter = r;
for (NSUInteger i=0; i<count; i++)
{
// get star style based on the index
CGContextSetFillColorWithColor(context, [self fillColorForItemAtIndex:i]);
CGContextSetStrokeColorWithColor(context, [self strokeColorForItemAtIndex:i]);
// update position
CGContextMoveToPoint(context, xCenter, r * flip + r);
// draw the necessary star lines
for (NSUInteger k=1; k<5; k++)
{
float x = r * sin(k * theta);
float y = r * cos(k * theta);
CGContextAddLineToPoint(context, x + xCenter, y * flip + r);
}
// update horizontal center for the next star
xCenter += w + self.itemMargin;
// draw current star
CGContextClosePath(context);
CGContextFillPath(context);
CGContextStrokePath(context);
}
}
I'm trying to adapt an example provided by Apple in order to programmatically draw stars in line, the code is the following:
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetLineWidth(context, aSize);
for (NSUInteger i=0; i<stars; i++)
{
CGContextSetFillColorWithColor(context, aColor);
CGContextSetStrokeColorWithColor(context, aColor);
float w = item.size.width;
double r = w / 2;
double theta = 2 * M_PI * (2.0 / 5.0); // 144 degrees
CGContextMoveToPoint(context, 0, r);
for (NSUInteger k=1; k<5; k++)
{
float x = r * sin(k * theta);
float y = r * cos(k * theta);
CGContextAddLineToPoint(context, x, y);
}
CGContextClosePath(context);
CGContextFillPath(context);
}
The code above draws a perfect star, but is 1. displayed upside down 2. is black and without border. What I want to achive is to draw many stars on the same line and with the given style. I understand that I'm actually drawing the same path 5 times in the same position and that I have somehow to flip the context vertically, but after several tests I gave up! (I lack the necessary math and geometry skills :P)... could you please help me?
UPDATE:
Ok, thanks to CocoaFu, this is my refactored and working draw utility:
- (void)drawStars:(NSUInteger)count inContext:(CGContextRef)context;
{
// constants
const float w = self.itemSize.width;
const float r = w/2;
const double theta = 2 * M_PI * (2.0 / 5.0);
const float flip = -1.0f; // flip vertically (default star representation)
// drawing center for the star
float xCenter = r;
for (NSUInteger i=0; i<count; i++)
{
// get star style based on the index
CGContextSetFillColorWithColor(context, [self fillColorForItemAtIndex:i]);
CGContextSetStrokeColorWithColor(context, [self strokeColorForItemAtIndex:i]);
// update position
CGContextMoveToPoint(context, xCenter, r * flip + r);
// draw the necessary star lines
for (NSUInteger k=1; k<5; k++)
{
float x = r * sin(k * theta);
float y = r * cos(k * theta);
CGContextAddLineToPoint(context, x + xCenter, y * flip + r);
}
// update horizontal center for the next star
xCenter += w + self.itemMargin;
// draw current star
CGContextClosePath(context);
CGContextFillPath(context);
CGContextStrokePath(context);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
下面是在水平线上绘制 3 颗星的代码,它不太漂亮,但可能会有所帮助:
Here is code that will draw 3 stars in a horizontal line, it's is not pretty but it may help:
这是一个实现 buddhabrot 暗示的算法:
对我来说适用于大多数基本的恒星。测试从 2 分(是一颗好钻石!)到 9 星。
如果您想要点朝下的星星,请将减法更改为加法。
要绘制多个,请创建一个循环并多次调用此方法,每次传递一个新的中心。这应该很好地排列它们!
Here's an algorithm to implement what buddhabrot implied:
Works for me for most basic stars. Tested from 2 points (makes a good diamond!) up to 9 stars.
If you want a star with point down, change the subtraction to addition.
To draw multiples, create a loop and call this method multiple times, passing a new center each time. That should line them up nicely!
我更喜欢使用
CAShaperLayer
来实现drawRect
,因为它可以被动画化。这是一个将创建 5 点星形状的路径的函数:
然后它可以与 CAShapeLayer 一起使用,如下所示:
I prefer using a
CAShaperLayer
to implementingdrawRect
, as it can then be animated.Here's a function that will create a path in the shape of a 5 point star:
It can then be used with a CAShapeLayer like so: