我正在编写一个简单的QR 码生成器(只是为了好玩和学习一些 Obj-C),并且我正在跟踪连接的“模块”(即构成 QR 码的黑色方块)的轮廓。这是为了获得更好的向量输出,而不是简单地为每个模块制作一堆矩形。
长话短说,我的大纲跟踪代码有效——但前提是我确保在特定位置调用 NSLog!如果我删除NSLog
-call,代码会循环!除了记录,我实际上什么都不做。我记录什么并不重要;我只需要调用 NSLog 否则事情就会中断。
跟踪算法很简单:围绕连接模块的形状顺时针移动。当你碰到一个角落时,向右转,直到你回到形状的轮廓。再次到达起点时停止。该形状可以有两个共享一个角点的模块。因此,跟踪循环将两次命中该点。这是预期的,并且代码可以正确处理它 -如果我调用NSLog
.
否则,代码会在第一次看到某个点时说它是一个角,而第二次看到它不是一个角,这会导致跟踪循环。检测某个东西是否是角点不依赖于除了点的 x 和 y 坐标以及模块对象数组之外的任何东西——但是在跟踪进行时模块和数组都不会改变,所以给定相同的 x, y 你应该总是得到相同的结果。它确实如此——如果我打电话给NSLog
.
如果没有NSLog
,坐标(例如(10,9))是角上的瞬间,片刻之后(10,9)突然不被识别为角。但是使用-call NSLog
,(10,9)每次都被正确地视为角点。
再说一遍:我完全没有改变;我只是记录一些东西——任何东西!突然间它起作用了。这就像说 2 == 2 是真还是假,除非我告诉它记录 2 和 2,在这种情况下 2 == 2 总是正确的,因为它应该是。
这是片状代码。脱离上下文很难理解,但是有很多上下文,所以我希望这已经足够了。一切都是整数(没有模糊浮点值)。
do { // start going around the shape
// If this isn't here or simply commented out, the code loops.
NSLog(@"foobar"); // doesn't matter what I log - I just need to log something
// Branch: Is current x,y a corner-point? This should
// always return the same result given the same X and Y
// values, but it only does if NSLog is there!
if( [self cornerAtX:x Y:y] ) {
// add the point to the path
[path addPoint:NSMakePoint(x, y)];
// rotate the direction clockwise, until
// the direction is following the edge of the
// the shape again.
do {
dt = dx;
dx = -dy;
dy = dt;
} while( ![self boundaryFromX:x Y:y inDirectionX:dx Y:dy] );
}
// continue along direction
x += dx;
y += dy;
} while( !(sx == x && sy == y) ); // we're back to the start of the shape, so stop
如果有人能告诉我为什么 NSLog 可以使代码工作(或者更确切地说:为什么不使用 NSLog 会使工作代码中断),我很高兴听到它!我希望有人能理解它。