2012-05-10 10 views
7

मैं डेल्फी में कस्टम नियंत्रण कर रहा हूं (TCustomControl से विरासत में मिला) जिसमें कई बहुभुज सूची आइटम (अनियमित आकार) शामिल हैं। मुझे प्रति आइटम माउस इवेंट्स को लागू करने की ज़रूरत है, लेकिन पहले मुझे यह पता लगाने में सक्षम होना चाहिए कि माउस की स्थिति किसी दिए गए पॉलीगॉन (array of TPoint) के भीतर है या नहीं। मैं हिट टेस्ट संदेश (WM_NCHITTEST) पकड़ रहा हूं और यह वह जगह है जहां मुझे यह सत्यापन करने की आवश्यकता होगी। मेरे पास कई बहुभुज हैं, मैं प्रत्येक पॉलीगॉन आइटम के माध्यम से एक लूप करूँगा और यह जांचने के लिए यह जांच करूँगा कि माउस की एक्स/वाई स्थिति इस बहुभुज के भीतर है या नहीं।पहचानें कि कोई बिंदु बहुभुज के भीतर है या नहीं?

procedure TMyControl.WMNCHitTest(var Message: TWMNCHitTest); 
var 
    P: TPoint; //X/Y of Mouse 
    Poly: TPoints; //array of TPoint 
    X: Integer; //iterator 
    I: TMyListItem; //my custom list item 
begin 
    P.X:= Message.XPos; 
    P.Y:= Message.YPos; 
    for X := 0 to Items.Count - 1 do begin 
    I:= Items[X]; //acquire my custom list item by index 
    Poly:= I.Points; //acquire polygon points 

    //Check if Point (P) is within Polygon (Poly)...? 

    end; 
end; 
+0

बस इंगित करने के लिए, मुझे कोड 'पी: = स्क्रीनटॉक्लिएंट (पी) कोड की एक पंक्ति याद आ रही है,' केवल 'पीएक्स' और 'पी। वाई' असाइन करने के बाद। यह उन बिंदुओं को नियंत्रण के सापेक्ष होने के लिए स्क्रीन के सापेक्ष होने से परिवर्तित करता है। –

+0

बेशक यह 'पी: = स्क्रीनटॉक्लिएंट (प्वाइंट (संदेश.एक्सपीओएस, संदेश.वायपीओएस)) जितना आसान हो सकता है; '(कोड में 3 लाइनों को एक में बदलें) –

उत्तर

15

आप PtInRegion उपयोग कर सकते हैं: http://en.wikipedia.org/wiki/Point_in_polygon#Ray_casting_algorithm

अधिकांश कंप्यूटर ग्राफिक्स कक्षाएं एक उदाहरण के रूप में इस का उपयोग करें:

function PointInPolygon(Point: TPoint; const Polygon: array of TPoint): Boolean; 
var 
    rgn: HRGN; 
begin 
    rgn := CreatePolygonRgn(Polygon[0], Length(Polygon), WINDING); 
    Result := PtInRegion(rgn, Point.X, Point.Y); 
    DeleteObject(rgn); 
end; 
+0

यह मेरा पहला विचार भी था। मुझे लगता है कि एक जीडीआई क्षेत्र बनाने के ऊपरी हिस्से में बहुत बुरा नहीं है (?)। –

+4

@ एंड्रियास मुझे कल्पना नहीं है कि ओवरहेड खराब है। जीडीआई क्षेत्र बहुत हल्का होना चाहिए। यदि यह एक समस्या थी तो आप बहुभुज के साथ क्षेत्रों को कैश कर सकते थे। –

+0

बढ़िया! मुझे ओवरहेड के साथ बहुत अधिक समस्या नहीं होगी क्योंकि मुझे उम्मीद है कि इस नियंत्रण में 20 से अधिक सूची आइटम नहीं हैं (जो कि इस नियंत्रण के लिए पहले से ही बड़ी संख्या है)। –

5

आप रे कास्टिंग एल्गोरिथ्म यहां पाया उपयोग कर सकते हैं।

1

यह जांचना कि पॉलीगॉन के अंदर बिंदु क्या है, उस बिंदु के माध्यम से एक क्षैतिज रेखा की कल्पना करके किया जा सकता है, फिर बाएं से दाएं गिनती से यह कल्पना की जाती है कि यह कल्पना रेखा बहुभुज को पार करती है। यदि बिंदु को मारने से पहले बहुभुज क्रॉस की संख्या विषम है तो बिंदु अंदर है, यदि तब भी बिंदु बहुभुज के बाहर है।

0

एक और तकनीक है जिसे हम बड़े पैमाने पर उपयोग करते हैं, जिसमें किसी भी गणित को शामिल नहीं किया जाता है और किसी भी आकार के बेहद जटिल एम्बेडेड नियंत्रणों को संभाल सकता है। बस रंग-कोडित सभी भागों के साथ नियंत्रण की एक ऑफ-स्क्रीन छवि है (जैसा कि नीचे दी गई छवि में दिखाया गया है) कि उपयोगकर्ता क्लिक कर सकता है।

जैसे ही वे अपने माउस को ले जाते हैं, बस हमारे ऑफ-स्क्रीन छवि में माउस के नीचे पिक्सेल का रंग देखें और यह हमें बताता है कि वे किस बटन/नियंत्रण पर हैं - सफेद इसके ऊपर नहीं है, और किसी श्रृंखला विभिन्न भागों के लिए रंगों का।

Color mask

// छद्म कोड

function MouseOverControl(LocalMousePos:TPoint):ControlID; 
begin 
    //sanity check 
    Result:=IDNull; 
    if (LocalMouse.X < 0) or (LocalMouse.X > ControlWidth) or 
     (LocalMouse.Y < 0) or (LocalMouse.Y > ControlHeight) then 
      exit; 
    case OffScreenControlMask.Canvas.Pixels[LocalMousePos.X,LocalMousePos.Y] of 
    clwhite:exit; 
    clRed:result:=ControlIDOne; 
    clGreen:result:=ControlIDTwo; 
    clBlue:result:=ControlIDThree; 
    ... etc 
    end; 
end; 

नोट: संलग्न रंग मास्क चित्र (और पांच समान परिपत्र एक केंद्र बटन के साथ चतुर्थ भाग में टूट नियंत्रण का प्रतिनिधित्व करता है के बाद से वे सभी एक ही रंग का उपयोग करें हमारे पास प्रत्येक रंग के लिए स्थिरांक होते हैं और हम निर्धारित करते हैं कि माउस में से प्रत्येक में एक साधारण एक्सपोज़िशन द्वारा कौन सा माउस खत्म हो गया है) के साथ उनके दाहिनी ओर एक अनियमित नियंत्रण और नीचे एक सेट या आयताकार बटन के साथ।

संबंधित मुद्दे

 संबंधित मुद्दे