有没有办法找出两个CGPathRef是否相交。在我的例子中,所有CGPath都有closePath。
例如,我有两条路。一条路径是以一定角度旋转的矩形,另一条路径是弯曲路径。两条路径的起源将经常变化。在某些时候,它们可能相交。我想知道它们什么时候相交。如果您有任何解决方案,请告诉我。
提前致谢
答案 0 :(得分:3)
将一条路径设为剪切路径,绘制另一条路径,然后搜索在裁剪过程中幸存的像素:
// initialise and erase context
CGContextAddPath(context, path1);
CGContextClip(context);
// set fill colour to intersection colour
CGContextAddPath(context, path2);
CGContextFillPath(context);
// search for pixels that match intersection colour
这是因为裁剪=相交。
不要忘记,交叉点取决于内在性的定义,其中有几个。此代码使用了绕组数填充规则,您可能需要偶数奇数规则或其他内容。如果内在性不能让你夜不能寐,那么这段代码应该没问题。
我之前的回答是将透明曲线绘制到RGBA上下文。这个解决方案优于旧解决方案,因为它是
谁可以要求更多?
我想你可以要求一个完整的实现,准备削减''''',但这会破坏乐趣并混淆一个简单的答案。
年龄较大,难以理解并且缺乏有效的答案
将50%透明度的CGPathRefs
单独绘制到归零的CGBitmapContextCreate
- RGBA内存缓冲区,并检查任何像素值> 128.这适用于任何支持CoreGraphics(即iOS和OSX)的平台。
在伪代码中
// zero memory
CGContextRef context;
context = CGBitmapContextCreate(memory, wide, high, 8, wide*4, CGColorSpaceCreateDeviceRGB(), kCGImageAlphaPremultipliedLast);
CGContextSetRGBFillColor(context, 1, 1, 1, 0.5); // now everything you draw will be at 50%
// draw your path 1 to context
// draw your path 2 to context
// for each pixel in memory buffer
if(*p > 128) return true; // curves intersect
else p+= 4; // keep looking
让光栅化版本的分辨率为您的精度,并选择精度以满足您的性能需求。
答案 1 :(得分:0)
1)没有任何CGPath
API可以执行此操作。但是,你可以做数学计算。看一下关于Bezier curves的维基百科文章,看看如何实现CGPath中的曲线。
2)这在我期望的iPhone上会很慢但是你可以将两条路径填充到不同颜色的缓冲区(比如红色和蓝色,alpha = 0.5),然后遍历缓冲区找到任何颜色交叉点处出现的像素。这将非常缓慢。
答案 2 :(得分:-1)
对于iOS,似乎忽略了alpha混合。
相反,您可以进行颜色混合,这将实现相同的效果,但不需要alpha:
CGContextSetBlendMode(context, kCGBlendModeColorDodge);
CGFloat semiTransparent[] = { .5,.5,.5,1};
输出图像中的像素为:
完整的绘图代码:
-(void) drawFirst:(CGPathRef) first second:(CGPathRef) second into:(CGContextRef)context
{
/** setup the context for DODGE (everything gets lighter if it overlaps) */
CGContextSetBlendMode(context, kCGBlendModeColorDodge);
CGFloat semiTransparent[] = { .5,.5,.5,1};
CGContextSetStrokeColor(context, semiTransparent);
CGContextSetFillColor(context, semiTransparent);
CGContextAddPath(context, first);
CGContextFillPath(context);
CGContextStrokePath(context);
CGContextAddPath(context, second);
CGContextFillPath(context);
CGContextStrokePath(context);
}
检查输出的完整代码:
[self drawFirst:YOUR_FIRST_PATH second:YOUR_SECOND_PATH into:context];
// Now we can get a pointer to the image data associated with the bitmap
// context.
BOOL result = FALSE;
unsigned char* data = CGBitmapContextGetData (context);
if (data != NULL) {
for( int i=0; i<width; i++ )
for( int k=0; k<width; k++ )
{
//offset locates the pixel in the data from x,y.
//4 for 4 bytes of data per pixel, w is width of one row of data.
int offset = 4*((width*round(k))+round(i));
int alpha = data[offset];
int red = data[offset+1];
int green = data[offset+2];
int blue = data[offset+3];
if( red > 254 )
{
result = TRUE;
break;
}
}
最后,这是来自另一个SO答案的略微修改的代码...用于在iOS 4,iOS 5上创建RGB空间的完整代码,它将支持上述功能:
- (CGContextRef) createARGBBitmapContextWithFrame:(CGRect) frame
{
/** NB: this requires iOS 4 or above - it uses the auto-allocating behaviour of Apple's method, to reduce a potential memory leak in the original StackOverflow version */
CGContextRef context = NULL;
CGColorSpaceRef colorSpace;
void * bitmapData;
int bitmapByteCount;
int bitmapBytesPerRow;
// Get image width, height. We'll use the entire image.
size_t pixelsWide = frame.size.width;
size_t pixelsHigh = frame.size.height;
// Declare the number of bytes per row. Each pixel in the bitmap in this
// example is represented by 4 bytes; 8 bits each of red, green, blue, and
// alpha.
bitmapBytesPerRow = (pixelsWide * 4);
bitmapByteCount = (bitmapBytesPerRow * pixelsHigh);
// Use the generic RGB color space.
colorSpace = CGColorSpaceCreateDeviceRGB();
if (colorSpace == NULL)
{
fprintf(stderr, "Error allocating color space\n");
return NULL;
}
// Create the bitmap context. We want pre-multiplied ARGB, 8-bits
// per component. Regardless of what the source image format is
// (CMYK, Grayscale, and so on) it will be converted over to the format
// specified here by CGBitmapContextCreate.
context = CGBitmapContextCreate (NULL,
pixelsWide,
pixelsHigh,
8, // bits per component
bitmapBytesPerRow,
colorSpace,
kCGImageAlphaPremultipliedFirst
//kCGImageAlphaFirst
);
if (context == NULL)
{
fprintf (stderr, "Context not created!");
}
// Make sure and release colorspace before returning
CGColorSpaceRelease( colorSpace );
return context;
}