Iphone CGPathRef交叉口
是否有办法确定两个CGPathRef是否相交。在我的例子中,所有的cgpath都有closePath 例如,我有两条路径。一条路径是以一定角度旋转的矩形,另一条路径是弯曲路径。两条路径原点将频繁更改。在某个点上,它们可能相交。我想知道它们何时相交。如果你有什么解决办法,请告诉我 提前感谢1)没有任何Iphone CGPathRef交叉口,iphone,cocoa,cocoa-touch,core-graphics,Iphone,Cocoa,Cocoa Touch,Core Graphics,是否有办法确定两个CGPathRef是否相交。在我的例子中,所有的cgpath都有closePath 例如,我有两条路径。一条路径是以一定角度旋转的矩形,另一条路径是弯曲路径。两条路径原点将频繁更改。在某个点上,它们可能相交。我想知道它们何时相交。如果你有什么解决办法,请告诉我 提前感谢1)没有任何CGPathAPI来执行此操作。但是,你可以做数学来解决这个问题。看看维基百科上的这篇文章,看看CGPath中的曲线是如何实现的 2) 这在iPhone上可能会很慢,但你可以用不同的颜色(比如,红色和
CGPath
API来执行此操作。但是,你可以做数学来解决这个问题。看看维基百科上的这篇文章,看看CGPath中的曲线是如何实现的
2) 这在iPhone上可能会很慢,但你可以用不同的颜色(比如,红色和蓝色,alpha=0.5)将这两条路径填充到缓冲区中,然后在缓冲区中迭代以查找交叉点处出现的任何像素。这将非常缓慢。将一条路径设置为剪辑路径,绘制另一条路径,然后搜索剪辑过程中幸存下来的像素:
// 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上下文中绘制透明曲线。此解决方案优于旧方案,因为它是
cgpathref
分别以50%的透明度绘制到归零的CGBitmapContextCreate
-ed 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
让光栅化版本的分辨率作为您的精度,并选择适合您的性能需要的精度。对于iOS,alpha混合似乎被忽略 相反,您可以进行颜色混合,这将实现相同的效果,但不需要alpha:
CGContextSetBlendMode(context, kCGBlendModeColorDodge);
CGFloat semiTransparent[] = { .5,.5,.5,1};
输出图像中的像素将为:
- RGB=0,0,0=(0.0f)。。。无路
- RGB=64,64,64=(0.25f)。。。一条路,没有交叉口
- RGB=128128=(0.5f)。。。两条路,找到交叉点
-(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;
}
}
谢谢你的解决方案。但是,我并不擅长核心图形。我们如何检索和检查非白色像素。向下投票,因为这似乎不起作用-它不会在iOS上添加颜色值,它只是替换它们。我浏览了文档,尝试了不同的颜色空间配置,看看是否有办法让它工作,但没有成功如果你找不到一种方法让你的透明代码工作,开始一个新的问题。如果你有代码回答这个问题,那就太好了。现在,这是一个理论上的答案,在实践中似乎不起作用(问题被标记为iPhone,你的答案是“如果..iPhone…可能必须”。我的经验是:试过了,没用)。我不希望其他人走上和我一样的死胡同。这不是一个简单的答案,你需要做一些工作。任何人都可以看到iOS可以绘制透明的路径,所以你的代码一定被窃听了。开始一个“为什么这段代码不绘制透明的CGPathRefs?”问题。我已经在我的答案中添加了更多的细节,但我认为要么你的CGContext配置错误,要么你没有单独绘制路径,或者有其他问题。一旦你让它工作起来,你可以随意发布你的代码,这将是一个更好的答案。iOS不会忽略alpha。检查您的代码-您是否尝试过使用KCGIMAGEAlphaPremultipledLast创建CGContext?我认为您的透明度问题是由于您创建了一个ARGB位图,但指定了RGBA颜色。在ARGB中,你的半透明颜色是一种美丽的矢车菊蓝色,带有50%的阿尔法。请尝试明确的CGContextSetRGBFillColor,并告诉我这是否解决了问题。p、 我已经更新了我的解决方案,以避免这种令人烦恼的透明度问题。KCGIMAGEALPHAPPremultipledLast(以及所有变体)失败。该方法称为“ARGB”,但其中没有指定alpha通道的位置-AFAIC读取苹果的文档,位图没有明确的alpha通道,苹果公司根据传入的颜色参考进行内部处理。苹果公司的文档将该颜色参考数组定义为RGBA。或者我遗漏了什么?阿尔法是第一位的,因为kgimagealphapremultipledfirst记录在CGImage.h中。位图可以有一个alpha通道,CGColorRef肯定会定义顺序,但您使用的是一个裸组件数组(剪切粘贴混合?),这很可能取决于位图布局。不知道为什么kCGImageAlphaPremultipliedLast失败了,它从2009年就开始为我工作了。RGBA,tho没有什么特别之处,只是它与OpenGLES 1纹理很好地匹配。#2实际上非常快,是解决某些问题(例如寻找笔划的交点而不是填充)的绝佳方法。
- (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;
}