我已經創建了一個程序,將鼠標限制在基於黑色/白色位圖的特定區域。該程序是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