【问题标题】:CoreGraphics draw intersection of ellipsesCoreGraphics 绘制椭圆的交点
【发布时间】:2013-03-20 00:06:19
【问题描述】:

我正在编写一个左侧有图例的 ViewController(标签和彩色框的垂直列表:Category1:黄色,Category2:gree,Category 3:蓝色等......)

用户可以点击列表中的一个项目,然后在 UIView 中绘制一个椭圆。我正在跟踪触摸事件,并且可以使用核心图形毫无问题地绘制椭圆。

下一步是绘制两个集合的交集。假设用户绘制了一个绿色椭圆和一个红色椭圆,它们有些重叠。我想将交叉点涂成黄色(红色+绿色=黄色),但对如何做到这一点没有任何想法。

我已经能够使用

此外,我需要一种方法让用户点击 UIImage 中的一个点,然后检索该像素所在的所有集合的交集。

【问题讨论】:

  • 这可以很容易地使用矩形而不是椭圆来完成。在用户端你会怎么想?你宁愿看到椭圆吗?即使您使用它们,它们也不会像矩形那样直接使用。

标签: iphone ios ipad


【解决方案1】:

如果您使用 Core Graphics 绘制椭圆,您可以更改 blend mode 以创建不同的外观。您想要的混合模式是添加,但 Core Graphics 似乎不支持它(可能是由于 Quantel 专利,尽管我认为它已经过期)。您可以通过使用 50% alpha 和使用普通模式创建类似的效果。或者也许其他模式之一会提供看起来更好的东西。

如果这不起作用,您可以在 OpenGL 中使用 additive blending 来完成。

【讨论】:

  • 您好,感谢您的建议。我在上图中使用了 50% 的 alpha。由于颜色的选择,它看起来并不那么好(它们不会以有趣的方式混合)。我知道 OpenGL 可以完成这项工作,但为了简单起见,我宁愿将其保留为 CG。 GLKit 让事情变得更简单了,但它仍然没有 CG 那么简单。
  • 好吧,试试你建议的颜色(例如,红色和绿色应该变成黄色)。您可以与CGContextSetBlendMode() 一起使用的任何其他混合模式看起来不错吗? kCGBlendModeScreen 是这样的一个非常好的选择。
【解决方案2】:

答案来自 user1118321,但我发布此答案是为了内嵌图片而不是内嵌回复。首先,我为维恩图选择了一组更好的颜色:

这些颜色相互重叠和隐藏。解决方案是使用 kCGBlendModeScreen:

但是,这增强了原始颜色。解决方案是将背景设置为黑色:

对于那些好奇或懒惰的代码,这里是一些代码。在 touchesBegan/Ended/Moved 事件中,我正在创建 SMVennObjects,然后在 drawRect 中绘制它们。 SMVennObject 仅包含两个 CGPoints 和一个 UIColor(使用静态 int 按顺序分配)。

// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect{        
    for(NSUInteger index = 0; index < self.vennObjects.count; index++){
        NSLog(@"drawing index %d", index);
        SMVennObject* vo = [self.vennObjects objectAtIndex:index];
        [self drawVennObject:vo context:UIGraphicsGetCurrentContext()];
    }
}

-(void)drawVennObject:(SMVennObject*)vo context:(CGContextRef)cgContext{
    if((vo.pointBegin.x == 0 && vo.pointBegin.y == 0) ||
       (vo.pointEnd.x == 0 && vo.pointEnd.y == 0)){
        return;
    }

    CGContextBeginPath(cgContext);
    CGContextSetLineWidth(cgContext, 2.0f);

    // Convert UIColor to raw values
    CGFloat red = 0.0;
    CGFloat green = 0.0;
    CGFloat blue = 0.0;
    CGFloat alpha = 0.0;
    [vo.color getRed:&red green:&green blue:&blue alpha:&alpha];
    alpha = 1.0;
    CGFloat color[4] = {red, green, blue, alpha};


    CGContextSetBlendMode(cgContext, kCGBlendModeScreen);

    CGRect r = CGRectMake(MIN(vo.pointBegin.x, vo.pointEnd.x),
                          MIN(vo.pointBegin.y, vo.pointEnd.y),
                          fabs(vo.pointBegin.x - vo.pointEnd.x),
                          fabs(vo.pointBegin.y - vo.pointEnd.y));

    // Draw ellipse
    CGContextSetFillColor(cgContext, color);
    CGContextFillEllipseInRect(cgContext, r);

    // Draw outline of ellipse
    CGContextSetStrokeColor(cgContext, color);
    CGContextStrokeEllipseInRect(cgContext, r);

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多