2

2 つの質問があります。

  1. CALayer で、2 つの円が交差しているかどうかを知る方法はありますか?
  2. 3 つの円が交差している場合、交差した領域を強調表示する方法はありますか?

CAShapeLayer を使用して円を描画しています。

- (CAShapeLayer *)circleForRadius:(CGFloat)iRadius withColor:(CGColorRef)iColor andDashPattern:(BOOL)isDashPattern {
CAShapeLayer *aSignalcircle = [CAShapeLayer layer];
aSignalcircle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * iRadius, 2.0 * iRadius) cornerRadius:iRadius].CGPath;
aSignalcircle.position = CGPointMake(0.0 - iRadius, 0.0 - iRadius);
aSignalcircle.fillColor = [UIColor clearColor].CGColor;
aSignalcircle.strokeColor = iColor;
aSignalcircle.lineWidth = kPSSignalStrokeWidth;

if (self.enableShadow) {
    aSignalcircle.shadowColor = [UIColor blackColor].CGColor;
    aSignalcircle.shadowOpacity = 0.5;
    aSignalcircle.shadowOffset = CGSizeMake(0, 0.25);
    aSignalcircle.shadowRadius = 0.5;
}

if (isDashPattern) {
    aSignalcircle.lineDashPattern = @[@1, @1];
}

return aSignalcircle;

}

以下のコードを使用してコンテキスト パスをクリッピングしようとしましたが、期待どおりに出力されません。

- (void)drawRect:(CGRect)rect
{
    CGFloat iRadius = 20.0;
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();
    CAShapeLayer *aSignalcircle = [CAShapeLayer layer];
    aSignalcircle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * iRadius, 2.0 * iRadius) cornerRadius:iRadius].CGPath;
    aSignalcircle.position = CGPointMake(10.0 , 10.0);
    aSignalcircle.fillColor = [UIColor clearColor].CGColor;
    aSignalcircle.strokeColor = [UIColor redColor].CGColor;
    aSignalcircle.lineWidth = 1.0;
    CGContextAddPath(context, aSignalcircle.path);
    CGContextClip(context);

    CAShapeLayer *aSignalcircle1 = [CAShapeLayer layer];
    aSignalcircle1.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * iRadius, 2.0 * iRadius) cornerRadius:iRadius].CGPath;
    aSignalcircle1.position = CGPointMake(30.0 , 10.0);
    aSignalcircle1.fillColor = [UIColor clearColor].CGColor;
    aSignalcircle1.strokeColor = [UIColor redColor].CGColor;
    aSignalcircle1.lineWidth = 1.0;
    CGContextAddPath(context, aSignalcircle1.path);
    CGContextClip(context);


    CAShapeLayer *aSignalcircle2 = [CAShapeLayer layer];
    aSignalcircle2.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * iRadius, 2.0 * iRadius) cornerRadius:iRadius].CGPath;
    aSignalcircle2.position = CGPointMake(25.0 , 30.0);
    aSignalcircle2.fillColor = [UIColor clearColor].CGColor;
    aSignalcircle2.strokeColor = [UIColor redColor].CGColor;
    aSignalcircle2.lineWidth = 1.0;
    CGContextAddPath(context, aSignalcircle2.path);

    [[UIColor grayColor] set];
    CGContextFillPath(context);

// Temp addition to see how the circles are looking on screen
    [self.layer addSublayer:aSignalcircle];
    [self.layer addSublayer:aSignalcircle1];
    [self.layer addSublayer:aSignalcircle2];
}

出力は次のようになります。

ここに画像の説明を入力

4

3 に答える 3

2

2 番目の質問では、次のコードを使用して交差領域を強調表示できます。

// Add first path and clip
CGContextAddPath(context, circle1.path);
CGContextClip(context);

// Add second path and clip
CGContextAddPath(context, circle2.path);
CGContextClip(context);

// Add third path and draw it. This means it'll be drawn within the clipping area
CGContextAddPath(context, circle3.path);
[[UIColor redColor] set];
CGContextFillPath(context);
于 2013-06-25T21:28:33.977 に答える
0

2 つの円の半径とその中心がわかっている場合、それらが互いに交差しているかどうかは非常に簡単にわかります。

// Supposing the layers have the circles at their center,
// which reading your code, it looks like it.
// Obtaining this values might be simpler in your code.
CGPoint center1 = circleLayer1.position;
CGPoint center2 = circleLayer2.position;
CGFloat radius1 = circleLayer1.bounds.size.width / 2.f;
CGFloat radius2 = circleLayer2.bounds.size.width / 2.f;

// Squared distance between the two circle centers
CGFloat distance2 = (center2.x - center1.x) * (center2.x - center1.x);
distance2 += (center2.y - center2.y) * (center2.y - center2.y);

// Squared sum of the two radii
CGFloat sumRadii2 = (radius1 + radius2) * (radius1 + radius2);

// The will intersect if the sum of the radii is larger than the distance)
BOOL intersection = sumRadii2 >= distance2;

交差点あたりは……まぁ、難しいですね。幾何学の本をよく読み直す必要があると思います。

アップデート:

あなたのソリューションと Hejazi のソリューションに基づいて構築します。

作成しているパス座標は各レイヤーに対して相対的であるため、それらを交差させる前に、それらを変換して適切な場所に描画する必要があります。

- (void)drawRect:(CGRect)rect
{
    CGFloat iRadius = 20.0;
    // Drawing code
    CGContextRef context = UIGraphicsGetCurrentContext();
    CAShapeLayer *aSignalcircle = [CAShapeLayer layer];
    aSignalcircle.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * iRadius, 2.0 * iRadius) cornerRadius:iRadius].CGPath;
    aSignalcircle.position = CGPointMake(10.0 , 10.0);
    aSignalcircle.fillColor = [UIColor clearColor].CGColor;
    aSignalcircle.strokeColor = [UIColor redColor].CGColor;
    aSignalcircle.lineWidth = 1.0;

    // Add this line
    CGPathRef translatedPath = CGPathCreateCopyByTransformingPath(aSignalcircle.path, CGAffineTransformMakeTranslation(aSignalcircle.position.x, aSignalcircle.position.y));

    CGContextAddPath(context, translatedPath);
    CGContextClip(context);

    // Release here
    CGPathRelease(translatedPath);

    CAShapeLayer *aSignalcircle1 = [CAShapeLayer layer];
    aSignalcircle1.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * iRadius, 2.0 * iRadius) cornerRadius:iRadius].CGPath;
    aSignalcircle1.position = CGPointMake(30.0 , 10.0);
    aSignalcircle1.fillColor = [UIColor clearColor].CGColor;
    aSignalcircle1.strokeColor = [UIColor redColor].CGColor;
    aSignalcircle1.lineWidth = 1.0;

    // Same here
    translatedPath = CGPathCreateCopyByTransformingPath(aSignalcircle1.path, CGAffineTransformMakeTranslation(aSignalcircle1.position.x, aSignalcircle1.position.y));
    CGContextAddPath(context, aSignalcircle1.path);
    CGContextClip(context);
    CGPathRelease(translatedPath);    

    CAShapeLayer *aSignalcircle2 = [CAShapeLayer layer];
    aSignalcircle2.path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 2.0 * iRadius, 2.0 * iRadius) cornerRadius:iRadius].CGPath;
    aSignalcircle2.position = CGPointMake(25.0 , 30.0);
    aSignalcircle2.fillColor = [UIColor clearColor].CGColor;
    aSignalcircle2.strokeColor = [UIColor redColor].CGColor;
    aSignalcircle2.lineWidth = 1.0;

    // And finally here
    CGPathRef translatedPath = CGPathCreateCopyByTransformingPath(aSignalcircle2.path, CGAffineTransformMakeTranslation(aSignalcircle2.position.x, aSignalcircle2.position.y));
    CGContextAddPath(context, aSignalcircle2.path);
    CGPathRelease(translatedPath);

    [[UIColor grayColor] set];
    CGContextFillPath(context);

// Temp addition to see how the circles are looking on screen
    [self.layer addSublayer:aSignalcircle];
    [self.layer addSublayer:aSignalcircle1];
    [self.layer addSublayer:aSignalcircle2];
}

私はテストしていませんが、サブレイヤーがパスを描画する新しいレイヤーにパスを配置する必要があります。それが機能するかどうか教えてください。

于 2013-06-25T21:24:12.450 に答える