2010-05-25 15 views
6

¿Cómo puedo simular un spray como la pintura para ventanas? Creo que crea puntos al azar, ¿cuál es tu opinión?Simular un spray

+0

¿Se trata de crear un spray con C# específicamente? Si no, ¿por qué está etiquetado "C#"? –

+0

Sí, esto se trata de crear un spray en C# –

+0

Funciona para mí, entonces. A veces es un poco confuso cuando una pregunta tiene una etiqueta, pero la pregunta real suena muy general y realmente no menciona ninguna relación con la etiqueta. Gracias, Hesam. –

Respuesta

5

Sí, yo diría que colorea píxeles aleatorios dentro de un cierto radio del punto de selección. También es probable que haya un retraso entre la coloración de un píxel y el otro, porque las máquinas de hoy en día son lo suficientemente rápidas como para poder colorear todos los píxeles posibles (siempre que el radio sea pequeño) antes de poder soltar el botón del mouse.

Además, creo que el algoritmo que usa Paint puede seleccionar un píxel para pintar aunque ya haya sido pintado, ya que a veces puede terminar con un círculo pintado con algunos píxeles sin pintar en el interior.

+0

'También es probable que haya un retraso de tiempo entre la coloración de un píxel y el otro"; solo pinta si el mouse se movió de un cuadro al siguiente. –

+1

@BlueRaja, acabo de abrir mspaint y mantuve presionado el botón del mouse. El círculo se llenó lentamente sin mover el mouse. FYI. –

+0

Además, tenga en cuenta que rocía con un factor de transparencia. Y si un píxel se rocía sobre otro píxel, la transparencia será más opaca. Well Paint no hace esto, pero Photoshop sí – Icemanind

-1

Creo que es difícil encontrar una muestra en C#. A continuación, presento una manera de comenzar su viaje en esto. Aquí estoy usando un pincel de textura.

private void Button1_Click(System.Object sender, System.EventArgs e) 
{ 
    try 
    { 
     Bitmap image1 = (Bitmap)Image.FromFile(@"C:\temp\mybrush.bmp", true); 

     TextureBrush t = new TextureBrush(image1); 
     t.WrapMode = System.Drawing.Drawing2D.WrapMode.Tile; 
     Graphics formGraphics = this.CreateGraphics(); 
     formGraphics.FillEllipse(t, new RectangleF(90.0F, 110.0F, 100, 100)); 
     formGraphics.Dispose(); 

    } 
    catch (System.IO.FileNotFoundException) 
    { 
     MessageBox.Show("Image file not found!"); 
    } 

} 

como Jesse dijo, creo que debería encontrar un algoritmo para distribuir píxeles aleatorios.

3

El patrón para pintura en aerosol sería semi-aleatorio. Si sacas una lata de Krylon y rocias lentamente una línea en una pared, terminas con una línea ancha y sólida que se desvanece hacia el fondo con un degradado alrededor de los bordes. Rocía en un lugar durante diez segundos y obtienes un gran punto en el centro en el que el color está completamente saturado, con un degradado radial al fondo.

So- sus variables para la simulación incluyen:

  • tiempo de mantenimiento de la "pulverizador" (botón del ratón)
  • movimiento de la "puede" (ratón)
  • velocidad del "puede" (los movimientos rápidos forman una línea liviana e insaturada. Los movimientos lentos forman una línea gruesa y saturada con un gradiente)
  • patrón de dispersión: ¿el spray está enfocado como un aerógrafo, o grande como una lata de aerosol?
  • "Distancia": ¿Qué tan lejos está el "rociador" del "lienzo"?
2

Ha recibido varias respuestas que lo indican en la dirección correcta para comenzar a manejar la experiencia del usuario del efecto de pulverización. En función de su respuesta a mi comentario, también necesita un algoritmo para generar los puntos aleatorios dentro del radio.

Hay varias maneras de hacerlo, y probablemente la más obvia sea usar polar coordinates para seleccionar el punto aleatorio y luego transformar la coordenada polar en una coordenada cartesiana (x, y) para representar el píxel. Aquí hay un ejemplo simple de este enfoque. Para mantener las cosas simples, acabo de dibujar una elipse simple de 1x1 para cada punto.

private Random _rnd = new Random(); 
private void Form1_MouseDown(object sender, MouseEventArgs e) 
{  
    int radius = 15; 

    using (Graphics g = this.CreateGraphics()) 
    { 
    for (int i = 0; i < 100; ++i) 
    { 
     // Select random Polar coordinate 
     // where theta is a random angle between 0..2*PI 
     // and r is a random value between 0..radius 
     double theta = _rnd.NextDouble() * (Math.PI * 2); 
     double r = _rnd.NextDouble() * radius; 

     // Transform the polar coordinate to cartesian (x,y) 
     // and translate the center to the current mouse position 
     double x = e.X + Math.Cos(theta) * r; 
     double y = e.Y + Math.Sin(theta) * r; 

     g.DrawEllipse(Pens.Black, new Rectangle((int)x - 1, (int)y - 1, 1, 1)); 
    } 
    } 
} 

Alternativamente, se puede seleccionar al azar coordenadas x, y del rectángulo que se ajusta el círculo de pulverización y usando el círculo ecuación r^2 = x^2 + y^2 prueba el punto para determinar si se encuentra dentro de el círculo, si lo hace, selecciona aleatoriamente otro punto y prueba de nuevo hasta que tenga un punto que se encuentre dentro del círculo. Aquí está una muestra rápida de este enfoque

private Random _rnd = new Random(); 
private void Form1_MouseDown(object sender, MouseEventArgs e) 
{  
    int radius = 15; 
    int radius2 = radius * 2; 

    using (Graphics g = this.CreateGraphics()) 
    { 
    double x; 
    double y; 

    for (int i = 0; i < 100; ++i) 
    {   
     do 
     { 
     // Randomy select x,y so that 
     // x falls between -radius..radius 
     // y falls between -radius..radius 
     x = (_rnd.NextDouble() * radius2) - radius; 
     y = (_rnd.NextDouble() * radius2) - radius; 

     // If x^2 + y^2 > r2 the point is outside the circle 
     // and a new point needs to be selected 
     } while ((x*x + y*y) > (radius * radius)); 

     // Translate the point so that the center is at the mouse 
     // position 
     x += e.X; 
     y += e.Y; 

     g.DrawEllipse(Pens.Black, new Rectangle((int)x - 1, (int)y - 1, 1, 1)); 
    } 
    } 
} 
0

Se puede crear un patrón de pulverización de varias intensidades mediante el muestreo de un número (en relación con la intensidad deseada y difundir) de coordenadas polares.Para ello, determinar una coordiate azar polar (ρ, θ) para cada muestra por:

ρ muestreada a partir de N (0, 1): Utilice un Normal (Gaussian) distribution para la distancia desde el centro exacto de su patrón de pulverización. No recuerdo si hay un generador variable normal en la biblioteca .NET. Si no hay, puede create one from a U(0, 1) generator.

θ muestreada de U (0, π): Muestra el componente angular de la Uniform Continuous Distribution. Sin pérdida de rendimiento o generalidad, en su lugar podría probar en U (n π, m π) para n < m, pero T (0, π) probablemente va a estar bien para lo que necesita.

las coordenadas cartesianas de cada muestra se dan por (T x + S x ρ cos θ, T y + S y ρ pecado θ) donde (T x, T y) es el centro del patrón de pulverización que desea crear; S x y S y son los factores de dispersión que desea tener en las direcciones xey respectivamente.

0

intente utilizar el temporizador

public partial class Form1 : Form 
{ 
    int Radious = 5; 
    Random _rnd = new Random(); 
    Timer T = new Timer(); 
    int InterVal = 1000; 
    MouseEventArgs MEA = null; 
    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     T.Tick += (O, E) => 
     { 
      StartSpray(); 
     }; 
     this.MouseDown += (O, E) => 
     { 
      MEA = E; 
      T.Interval = InterVal; 
      T.Start(); 

     }; 
     this.MouseUp += (O, E) => 
     { 
      T.Stop(); 
     }; 
    } 
    private void StartSpray() 
    { 
     Point P = DrawPoint(Radious, MEA.X, MEA.Y); 
     // Draw the point on any graphics area you can add the color or anything else 
    } 
    private Point DrawPoint(int Radious, int StatX, int StartY) 
    { 
     double theta = _rnd.NextDouble() * (Math.PI * 2); 
     double r = _rnd.NextDouble() * Radious; 
     Point P = new Point { X = StatX + Convert.ToInt32(Math.Cos(theta) * r), Y = StartY + Convert.ToInt32(Math.Sin(theta) * r) }; 
     return P; 
    }  
} 

modifique el intervalo y el radio.