2009-12-12 18 views
13

मैं रन टाइम पर उपयोग करने के लिए ग्रिड कार्यक्षमता में कुछ स्नैप बनाने की कोशिश कर रहा हूं लेकिन मुझे स्नैपिंग भाग में समस्याएं आ रही हैं। मैंने पैनल पर एक बिंदीदार ग्रिड सफलतापूर्वक खींचा है, लेकिन जब मैं पैनल में लेबल नियंत्रण जोड़ता हूं, तो लेबल के शीर्ष बाएं कोने को निकटतम बिंदु पर कैसे स्नैप करना है?सी # ग्रिड कार्यक्षमता के लिए स्नैप बनाएं

धन्यवाद

उत्तर

17

pos.x - pos.x% gridWidth यह

+1

बहुत बहुत धन्यवाद! – Nathan

+1

केप को ध्यान में रखें कि उपरोक्त कोड शून्य के करीब ग्रिडलाइन पर स्नैप करेगा। बाएं या दाएं स्नैप करने के लिए आप गीलेर pos.x% ग्रिड का परीक्षण कर सकते हैं ग्रिडविड्थ ग्रिडविड्थ/2 से अधिक या कम है याद रखें कि आपको शून्य से नीचे निर्देशांक के लिए एक अलग मामला मिलेगा। आपको आपको आवश्यक सभी टूल्स देना चाहिए। – Pedery

+1

यदि आपके पास gridWidth = 3. पॉइंटएक्स = 5 के लिए है, तो यह 3 पर मैप करना चाहिए जब इसे 6 पर मैप करना चाहिए। अधिक विस्तृत उत्तर के लिए मेरा उत्तर देखें। –

0

बस पूर्णांकों का उपयोग करें और विभाजन सिर्फ तुम्हारे लिए काम करेंगे करना चाहिए: निश्चित रूप से सिवाय सापेक्ष समाधान है

int xSnap = (xMouse/gridWidth) * gridWidth; 
int ySnap = (yMouse/gridHeight) * gridHeight; 

बहुत अधिक सुरुचिपूर्ण।

+0

आप ग्रिडविड्थ द्वारा गुणा और विभाजित कर रहे हैं। यह उन्हें हमेशा xmouse के बराबर छोड़ने के लिए रद्द कर देगा। – Julian

+2

-1: जैसा कि जूलियन ने कहा, प्राथमिक गणित से पता चलता है कि यह जवाब बकवास है – ssc

1
private enum SnapMode { Create, Move } 
private Size gridSizeModeCreate = new Size(30, 30); 
private Size gridSizeModeMove = new Size(15, 15); 

private Point SnapCalculate(Point p, Size s) 
{ 
    double snapX = p.X + ((Math.Round(p.X/s.Width) - p.X/s.Width) * s.Width); 
    double snapY = p.Y + ((Math.Round(p.Y/s.Height) - p.Y/s.Height) * s.Height); 
    return new Point(snapX, snapY); 
} 

private Point SnapToGrid(Point p, SnapMode mode) 
{ 
    if (mode == SnapMode.Create) 
     return SnapCalculate(p, gridSizeModeCreate); 
    else if (mode == SnapMode.Move) 
     return SnapCalculate(p, gridSizeModeMove); 
    else 
     return new Point(0, 0); 
} 
3

यहाँ एक समाधान है कि दौर निकटतम ग्रिड बात करने के लिए:

public static readonly Size Grid  = new Size(16, 16); 
    public static readonly Size HalfGrid = new Size(Grid.Width/2, Grid.Height/2); 

    // ~~~~ Round to nearest Grid point ~~~~ 
    public Point SnapCalculate(Point p) 
    { 
     int  snapX = ((p.X + HalfGrid.Width )/Grid.Width ) * Grid.Width; 
     int  snapY = ((p.Y + HalfGrid.Height)/Grid.Height) * Grid.Height; 

     return new Point(snapX, snapY); 
    } 
1

यह एक मेरे लिए बेहतर काम करता है के रूप में यह निर्भर करता है बिंदु से चलता है कि कैसे पास यह अगले या पिछले बांधना है पर -पॉइंट:

  if (pt.X % gridWidth < gridWidth/2) 
       pt.X = pt.X - pt.X % gridWidth; 
      else 
       pt.X = pt.X + (gridWidth - pt.X % gridWidth); 

      if (pt.Y % gridHeight < gridHeight/2) 
       pt.Y = pt.Y - pt.Y % gridHeight; 
      else 
       pt.Y = pt.Y + (gridHeight - pt.Y % gridHeight); 
14

मुझे नहीं लगता कि स्वीकृत उत्तर सही है। यहाँ कारण है कि:

अगर gridwidth = 3, 4 की तरह एक्स पर एक बिंदु 3 के लिए नक्शे चाहिए, लेकिन एक्स = 5 Pedery के जवाब का उपयोग कर 6. करने के लिए नक्शे चाहिए वे करेंगे 3.

सही के लिए करने के लिए दोनों नक्शा नतीजतन आपको इस तरह से गोल करने की आवश्यकता है (यदि अंक भिन्न होते हैं तो आप फ्लोट का उपयोग कर सकते हैं):

// आइए कहें।

int gridCubeWidth = 3; 
int gridCubeHeight = 3; 

int newX = Math.Round(oldX/gridCubeWidth) * gridCubeWidth; 
int newY = Math.Round(oldY/gridCubeHeight) * gridCubeHeight; 
संबंधित मुद्दे