2009-12-12 10 views
13

Estoy tratando de crear algunas funciones de ajuste a la cuadrícula que se utilizarán en tiempo de ejecución, pero estoy teniendo problemas con la parte de ajuste. He dibujado con éxito una cuadrícula punteada en un panel, pero cuando agrego un control de etiqueta al panel, ¿cómo hago para encajar la esquina superior izquierda de la etiqueta en el punto más cercano?C# Crear funcionalidad de ajuste a la cuadrícula

Gracias

Respuesta

17

pos.x - pos.x% gridwidth debe hacerlo

+1

Muchas gracias! – Nathan

+1

Tenga en cuenta que el código anterior se ajustará a la cuadrícula más cerca de cero sin embargo. Para mover hacia la izquierda o hacia la derecha, podrías, por ejemplo, probar si pos.x% gridWidth es mayor o menor que gridWidth/2. Recuerda que obtendrás un caso diferente para las coordenadas debajo de cero. Eso debería darte todas las herramientas que necesitas. – Pedery

+1

si tiene gridWidth = 3. para un puntoX = 5, se correlacionará con 3 cuando corresponda con 6. vea mi respuesta para obtener una respuesta más elaborada. –

0

Sólo tiene que utilizar números enteros y la división se acaba de trabajar para usted:

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

Excepto, por supuesto, es la solución de módulo mucho más elegante.

+0

Está multiplicando y dividiendo por gridWidth. Esto los cancelará, dejando esto para que siempre sea igual a xMouse. – Julian

+2

-1: como dijo @Julian, las matemáticas elementales muestran que esta respuesta es una tontería – 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

Aquí es una solución que rondas hasta el punto de la cuadrícula más cercana:

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

Esta funciona mejor para mí, ya que mueve el punto dependiendo de lo cerca que está a la siguiente o ceñidor anterior -punto de vista:

  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

No creo que la respuesta aceptada sea la correcta. He aquí por qué:

si el gridwidth = 3, el punto en x 4 como debería asignar a 3, pero x = 5 debe asignar a 6. usando la respuesta de Pedery lo harán tanto mapa para 3.

Para un correcto resultado debe redondear así (puede usar flotación si los puntos son fracciones):

// Digamos.

int gridCubeWidth = 3; 
int gridCubeHeight = 3; 

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