Simulate a spray
Asked Answered
E

6

6

How can i simulate a spray like windows paint ? i think it create points random , what is your opinion?

Extortion answered 25/5, 2010 at 16:54 Comment(6)
Is this about creating a spray using C# specifically? If not, why is this tagged "C#"?Gaslight
Yes this is about creating a spray in C#Extortion
Works for me, then. It's sometimes a bit confusing when a question has a tag, but the actual question sounds very general and doesn't really mention any relation to the tag. Thanks, Hesam.Gaslight
Did you need an routine for selecting the random point in a circle?Admeasurement
Yes i need . can you tell me how ?Extortion
I would say that this is the kind of question you should not ask here, but rather try and experiment with yourself. After all, there is a lot of art to it, but no strict rules.Kathe
R
5

Yes, I would say it colors random pixels within a certain radius of the selection point. There's also probably a time delay between the coloring of one pixel and the other, because machines today are fast enough to be able to color every possible pixel (As long as the radius is small) before you could let go of the mouse button.

Also, I think the algorithm that Paint uses can select a pixel to paint even if it already has been painted, since sometimes you can end up with a painted circle with a few unpainted pixels inside.

Robichaud answered 25/5, 2010 at 17:0 Comment(3)
There's also probably a time delay between the coloring of one pixel and the other - it only paints if the mouse has moved between one frame to the next.Biauriculate
@BlueRaja, I just opened up mspaint and held the mouse button down. The circle slowly filled up without my mouse moving. FYI.Adoptive
Also, keep in mind that it sprays with a transparency factor. And if a pixel gets sprayed over another pixel, the transparency will become more opaque. Well Paint doesn't do this, but Photoshop doesDeaton
J
3

The pattern for spray paint would be semi-random. If you get out a can of Krylon and slowly spray a line on a wall, you end up with a wide solid line that fades out to the background with a gradient around the edges. Spray in one spot for ten seconds, and you get a big dot in the center in which the color is fully saturated, with a radial gradient to the background.

So- your variables for simulation include:

  • Time holding the "sprayer" (mouse button)
  • Motion of the "can" (mouse)
  • Speed of the "can" (fast moves make a light, unsaturated line. Slow moves make a thick, saturated line with a gradient)
  • spread pattern: is the spray focused like an airbrush, or big like a spray can?
  • "Distance": How far away is the "sprayer" from the "canvas"?
Joanniejoao answered 25/5, 2010 at 17:12 Comment(0)
A
2

You have received a number of answers pointing you in the right direction to start handling the user experience of the spray effect. Based on your reponse to my comment you also need an algorithm for generating the random points within the radius.

There are a number of ways to do this, and probably the most obvious would be to use polar coordinates to select the random point and then transform the polar coordinate to a cartesian (x,y) coordinate to render the pixel. Here is a simple example of this approach. To keep things simple, I have just drawn a simple 1x1 ellipse for each point.

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));
    }
  }
}

Alternatively, you can randomly select x,y coordinates from the rectangle that fits the spray circle and using the circle equation r^2 = x^2 + y^2 test the point to determine if it lies inside the circle, if it does you randomly select another point and test again until you have a point that lies within the circle. Here is a quick sample of this approach

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));
    }
  }
}
Admeasurement answered 26/5, 2010 at 21:54 Comment(0)
O
0

You can create a spray pattern of various intensities by sampling some number (related to the desired intensity and spread) of polar coordinates. To do this, determine a random polar coordiate (ρ, θ) for each sample by:

ρ sampled from N(0, 1): Use a Normal (Gaussian) distribution for the distance from the exact center of your spray pattern. I don't recall if there's a normal variate generator in the .NET library. If there isn't, you can create one from a U(0, 1) generator.

θ sampled from U(0, π): Sample the angular component from the Uniform Continuous Distribution. Without loss of performance or generality, you could instead sample on U(nπ, mπ) for n < m, but U(0, π) will probably be fine for what you need.

The Cartesian coordinates of each sample are give by (Tx + Sxρ cos θ, Ty + Syρ sin θ) where (Tx, Ty) is the center of the spray pattern you want to create; Sx and Sy are the spread factors you want to have in the x and y directions respectively.

Overawe answered 6/7, 2010 at 2:38 Comment(0)
F
0

Try using the timer

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;
    }      
}

please modify the Interval and the radius.

Fuchsia answered 6/7, 2010 at 22:51 Comment(0)
N
-1

I think it's hard to find a sample on C#. Below I present a way to start your journey on this. Here I am using a texture brush.

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!");
    }

}

as Jesse said, I think you should find an algorithm to spread random pixels.

Nearly answered 25/5, 2010 at 17:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.