我已经创建了一个程序,将鼠标限制在基于黑色/白色位图的特定区域。该程序是100%原样运行的,但是使用不准确但快速的算法来重新定位鼠标,使其在区域外飘荡。如何确定鼠标在某个形状上的最近点?
目前,在区外的移动鼠标,基本上会发生什么情况是这样的:
- 一条线的区域和鼠标的新位置内预先定义的静点之间绘制。
- 其中该行相交所允许的区域的边缘点被找到。
- 鼠标移动到那一点。
这工作,但只适用完美与在正中央设置预先定义的点一个完美的圆。不幸的是,这绝不会是这样。该应用程序将使用各种矩形和不规则,无定形的形状。在这样的形状上,绘制的线与边相交的点通常不会是形状上与鼠标最近的点。
我需要创建一个新的算法,找到最接近的指向鼠标在允许区域边缘的新位置。我怎样才能做到这一点?优选地,该方法应该能够足够快地执行,以在将鼠标拖曳到该区域的边缘时给予平滑的鼠标移动。
(我这样做在OS目标C /可可X 10.7,但是,伪码是好的,如果你不想输入代码或者不知道目标C/C)
谢谢!
这是我目前的算法:
#import <Cocoa/Cocoa.h>
#import "stuff.h"
#import <CoreMedia/CoreMedia.h>
bool
is_in_area(NSInteger x, NSInteger y, NSBitmapImageRep *mouse_mask){
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
NSUInteger pixel[4];
[mouse_mask getPixel:pixel atX:x y:y];
if(pixel[0]!= 0){
[pool release];
return false;
}
[pool release];
return true;
}
CGEventRef
mouse_filter(CGEventTapProxy proxy, CGEventType type, CGEventRef event, NSBitmapImageRep *mouse_mask) {
CGPoint point = CGEventGetLocation(event);
float tX = point.x;
float tY = point.y;
if(is_in_area(tX,tY, mouse_mask)){
// target is inside O.K. area, do nothing
}else{
CGPoint target;
//point inside restricted region:
float iX = 600; // inside x
float iY = 500; // inside y
// delta to midpoint between iX,iY and tX,tY
float dX;
float dY;
float accuracy = .5; //accuracy to loop until reached
do {
dX = (tX-iX)/2;
dY = (tY-iY)/2;
if(is_in_area((tX-dX),(tY-dY),mouse_mask)){
iX += dX;
iY += dY;
} else {
tX -= dX;
tY -= dY;
}
} while (abs(dX)>accuracy || abs(dY)>accuracy);
target = CGPointMake(roundf(tX), roundf(tY));
CGDisplayMoveCursorToPoint(CGMainDisplayID(),target);
}
return event;
}
int
main(int argc, char *argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
stuff *stuff_doer = [[stuff alloc] init];
NSBitmapImageRep *mouse_mask= [stuff_doer get_mouse_mask];
CFRunLoopSourceRef runLoopSource;
CGEventMask event_mask;
event_mask = CGEventMaskBit(kCGEventMouseMoved) | CGEventMaskBit(kCGEventLeftMouseDragged) | CGEventMaskBit(kCGEventRightMouseDragged) | CGEventMaskBit(kCGEventOtherMouseDragged);
CGSetLocalEventsSuppressionInterval(0);
CFMachPortRef eventTap = CGEventTapCreate(kCGHIDEventTap, kCGHeadInsertEventTap, 0, event_mask, mouse_filter, mouse_mask);
if (!eventTap) {
NSLog(@"Couldn't create event tap!");
exit(1);
}
runLoopSource = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, eventTap, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), runLoopSource, kCFRunLoopCommonModes);
CGEventTapEnable(eventTap, true);
CFRunLoopRun();
CFRelease(eventTap);
CFRelease(runLoopSource);
[pool release];
exit(0);
}
这是可能被使用的区域位图的示例中,黑色是允许的区域。 这说明了为什么转换为多边形不方便或者甚至是合理的。
这些看起来很不错。看起来好像查找表可能实际上是两者中较容易实现的。我不确定你在谈论冗余计算和弗洛伊德 - 沃尔什哈尔。我会仔细看看的。因为表格会存储x和y,以表示最接近每个130万像素的点,那么占用多少空间?我的计算结果是4MB。 (每x 11位,每位11位,130万像素)这看起来是对的吗? – BumbleShrimp