Ant*_*ony 7 algorithm objective-c quartz-2d ios
考虑这个ASCII绘图:
A _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ D
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|
B C
Run Code Online (Sandbox Code Playgroud)
点A,B,C和D CGPoints在a中是已知的NSMutableArray并且已经用于创建填充CGPath.现在考虑这个图:
A _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ D
| |
| |
| |
| |
| H _ _ _ I |
| | | |
| | | |
| F _ _ _| | |
| | G | |
| | |_ _ _ K |
| | J | |
| | | |
|_ _ _ _| _ _ _ _ _ _ _ _ |_ _ _|
B E L C
Run Code Online (Sandbox Code Playgroud)
CGPointsE,F,G,H,I,J,K和L是已知的并且已被附加到末尾NSMutableArray.
问题
如何重新排列数组中的所有点以创建CGPath如下图所示的图形?
A _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ D
| |
| |
| |
| |
| H _ _ _ I |
| | | |
| | | |
| F _ _ _| | |
| | G | |
| | |_ _ _ K |
| | J | |
| | | |
|_ _ _ _| |_ _ _|
B E L C
Run Code Online (Sandbox Code Playgroud)
目前我创建一个CGPath- 如果我知道 - 的顺序CGpoints- 通过循环它们没有问题:
CGPoint firstPoint = [[points objectAtIndex:0] CGPointValue];
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, NULL, firstPoint.x, firstPoint.y);
for (int i = 0; i < [points count]; i++)
{
CGPathAddLineToPoint(path, NULL, [[points objectAtIndex:i] CGPointValue].x, [[points objectAtIndex:i] CGPointValue].y);
}
CGPathCloseSubpath(path);
Run Code Online (Sandbox Code Playgroud)
...但是这假定应该从数组i中的每个点绘制一条线到下一点i + 1.在上面的绘画,线就必须从绘制A ? B,B ? E,E ? F... K ? L,L ? C,C ? D.如果E不在B之后并且C不在阵列中的L之后(它们将不会),那么这显然不能正确绘制.
更多信息
CGPoints都应与之前和之后共享x或y协调CGPoint.其他可能的布局
A _ _ _ _ _ _ _ K P _ _ _ D
| | | |
| | | |
| | N _ _ _| |
| | | O |
| |_ _ _| |
| L M |
| |
| F _ _ _ G |
| | | |
| | |_ _ _ I |
| | H | |
| | | |
|_ _ _ _ _ _ _| |_ _ _|
B E J C
A _ _ _ _ _ _ _ _ _ _ M
| |
| |
| |_ _ _ _ _ _ O
| N |
| H _ _ _ I |
| | | |
| | | |
| F _ _ _| | |
| | G | |
| | |_ _ _ K |
| | J | |
| | | |
|_ _ _ _| |_ _ _|
B E L C
Run Code Online (Sandbox Code Playgroud)
我想这可能会做到。我用几组数字测试了它,它似乎有效。基本上,我从索引 0 处的点开始(任何起点都应该有效),将其添加到arrangedPoints数组中,然后查找具有相同 y 值的最近点——该点被添加到arrangedPoints中并从原始randomPoints中删除大批。然后,我在 x 方向上执行相同的操作并重复,直到 randomPoints 数组中只剩下一个点,并将其添加到arrangedPoints 的末尾。
-(void)arrangePoints:(NSMutableArray *) randomPoints {
NSMutableArray *arrangedPoints = [NSMutableArray array];
[arrangedPoints addObject:[randomPoints objectAtIndex:0]];
[randomPoints removeObjectAtIndex:0];
while (randomPoints.count > 1) {
//Look for the closest point that has the same y value
int yValueOfknownPoint = [[arrangedPoints lastObject] CGPointValue].y;
int xValueOfknownPoint = [[arrangedPoints lastObject] CGPointValue].x;
NSIndexSet *indSet = [randomPoints indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
return yValueOfknownPoint == [obj CGPointValue].y;
}];
NSLog(@"%d",indSet.count);
if (indSet.count == 1) {
[arrangedPoints addObject:[randomPoints objectAtIndex:indSet.firstIndex]];
[randomPoints removeObjectAtIndex:indSet.firstIndex];
}else{
__block int min = 10000000;
__block int foundIndex;
[indSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
int posibleMin = fabs(xValueOfknownPoint - [[randomPoints objectAtIndex:idx]CGPointValue].x);
if (posibleMin < min) {
min = posibleMin;
foundIndex = idx;
}
}];
[arrangedPoints addObject:[randomPoints objectAtIndex:foundIndex]];
[randomPoints removeObjectAtIndex:foundIndex];
}
//Look for the closest point that has the same x value
xValueOfknownPoint = [[arrangedPoints lastObject] CGPointValue].x;
yValueOfknownPoint = [[arrangedPoints lastObject] CGPointValue].y;
indSet = [randomPoints indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop){
return xValueOfknownPoint == [obj CGPointValue].x;
}];
if (indSet.count == 1) {
[arrangedPoints addObject:[randomPoints objectAtIndex:indSet.firstIndex]];
[randomPoints removeObjectAtIndex:indSet.firstIndex];
}else{
__block int min = 10000000;
__block int foundIndex;
[indSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
int posibleMin = fabs(yValueOfknownPoint - [[randomPoints objectAtIndex:idx]CGPointValue].y);
if (posibleMin < min) {
min = posibleMin;
foundIndex = idx;
}
}];
[arrangedPoints addObject:[randomPoints objectAtIndex:foundIndex]];
[randomPoints removeObjectAtIndex:foundIndex];
}
}
[arrangedPoints addObject:randomPoints.lastObject];
NSLog(@"%@",arrangedPoints);
}
Run Code Online (Sandbox Code Playgroud)
解决已知问题的一些补充点:
为了处理像 N 中的 G 和 M 这样的等距点,我想我应该将点集分开——而不是将所有东西放入一个数组中,我会保留原始矩形,以及单独出现的每个新点集。然后,当我构建路径时,我只会在我自己的点集中或原始矩形中查找点,而不是在任何其他点集中查找点。
为了解决所提出的问题,即自身加倍,我认为您必须确定一组点是否与边或角相交 - 我认为只有角点才会出现该问题。您可以通过查看其中 2 个点落在原始矩形的 2 条不同线上(而不是在同一条线上)来检查角点。然后,您必须计算缺失的点(上面最后一个示例中的假定点 p)并查看原始矩形的哪个点也相同,然后从路径中删除该点。我认为我的算法将正确工作。