2009-12-12 9 views
13

Sto cercando di creare alcune funzionalità di snap alla griglia da utilizzare in fase di esecuzione ma sto riscontrando problemi con la parte di snap. Ho disegnato con successo una griglia tratteggiata su un pannello ma quando aggiungo un controllo etichetta al pannello come faccio a far scattare l'angolo superiore sinistro dell'etichetta al punto più vicino?C# Crea funzionalità di snap alla griglia

Grazie

risposta

17

pos.x - pos.x% gridWidth dovrebbe farlo

+1

Grazie mille! – Nathan

+1

Ricordare che il codice sopra si attaccherà alla griglia più vicino allo zero. Per eseguire lo snap a sinistra o a destra è possibile testare se pos.x% gridWidth è più o meno di gridWidth/2. Ricordare che si otterrà un caso diverso per le coordinate sotto zero. Questo dovrebbe darti tutti gli strumenti di cui hai bisogno. – Pedery

+1

se si ha gridWidth = 3. per un puntoX = 5, verrà mappato a 3 quando dovrebbe mappare a 6. vedere la risposta per una risposta più elaborata. –

0

Basta usare numeri interi e divisione sarà solo lavorare per voi:

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

Tranne, naturalmente, la soluzione di modulo è molto più elegante

+0

Stai moltiplicando e dividendo per gridWidth. Questo li cancellerà lasciando sempre uguale xMouse. – Julian

+2

-1: come ha detto @Julian, la matematica elementare mostra che questa risposta non ha senso – 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

Ecco una soluzione che giri al punto della griglia più vicino:

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

Questo funziona meglio per me, come si muove il punto a seconda di quanto è vicino a successivo o gird precedente -point:

  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

Non credo che la risposta accettata sia corretta. Ecco perché:

se il gridwidth = 3, il punto su come x 4 dovrebbe mappare 3, ma x = 5 dovrebbe mappare 6. usando la risposta di Pedery saranno entrambi mappa per 3.

Per una corretta risultato è necessario arrotondare in questo modo (è possibile utilizzare float se i punti sono frazioni):

// Diciamo.

int gridCubeWidth = 3; 
int gridCubeHeight = 3; 

int newX = Math.Round(oldX/gridCubeWidth) * gridCubeWidth; 
int newY = Math.Round(oldY/gridCubeHeight) * gridCubeHeight; 
Problemi correlati