1

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

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

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

我已经能够使用 < 1.0 的 alpha 通道来完成此操作,如下图所示: 在此处输入图像描述

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

4

2 回答 2

1

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

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

于 2013-03-18T03:03:39.633 回答
0

答案来自 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);

}
于 2013-03-19T16:06:19.270 回答