Имитировать спрей - PullRequest
6 голосов
/ 25 мая 2010

Как я могу имитировать спрей, как краска для окон?я думаю, что это создает случайные очки, каково ваше мнение?

Ответы [ 6 ]

5 голосов
/ 25 мая 2010

Да, я бы сказал, что это цвет случайных пикселей в пределах определенного радиуса точки выбора. Вероятно, существует также временная задержка между окрашиванием одного пикселя и другого, потому что современные машины достаточно быстры, чтобы иметь возможность раскрашивать каждый возможный пиксель (пока радиус маленький), прежде чем вы сможете отпустить кнопку мыши.

Кроме того, я думаю, что алгоритм, который использует Paint, может выбрать пиксель для рисования, даже если он уже был нарисован, поскольку иногда вы можете получить нарисованный круг с несколькими неокрашенными пикселями внутри.

3 голосов
/ 25 мая 2010

Шаблон для аэрозольной краски будет полуслучайным. Если вы достанете банку с Krylon и медленно распыляете линию на стене, вы получите широкую сплошную линию, которая постепенно исчезает на заднем плане с градиентом по краям. Распылите в одном месте в течение десяти секунд, и вы получите большую точку в центре, в которой цвет полностью насыщен, с радиальным градиентом к фону.

Итак, ваши переменные для моделирования включают в себя:

  • Время удерживания «распылителя» (кнопка мыши)
  • Движение «консервной банки» (мыши)
  • Скорость «банки» (быстрые движения образуют легкую ненасыщенную линию. Медленные движения образуют толстую, насыщенную линию с градиентом)
  • Распространение: спрей сфокусирован как аэрограф, или большой, как аэрозольный баллончик?
  • «Расстояние»: как далеко «распылитель» от «холста»?
2 голосов
/ 27 мая 2010

Вы получили ряд ответов, указывающих вам правильное направление, чтобы начать работу с пользовательским эффектом распыления. На основании вашего ответа на мой комментарий вам также понадобится алгоритм генерации случайных точек в радиусе.

Есть несколько способов сделать это, и, вероятно, наиболее очевидным было бы использовать полярные координаты , чтобы выбрать случайную точку, а затем преобразовать полярную координату в декартову (x, y) координату. визуализировать пиксель. Вот простой пример такого подхода. Для простоты я нарисовал простой эллипс 1x1 для каждой точки.

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

В качестве альтернативы, вы можете случайным образом выбрать координаты x, y из прямоугольника, который соответствует окружности распыления, и с помощью уравнения окружности r ^ 2 = x ^ 2 + y ^ 2 проверить точку, чтобы определить, находится ли она внутри окружности, если он случайным образом выбирает другую точку и проверяет снова, пока у вас не будет точки, которая находится внутри круга. Вот краткий пример этого подхода

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 голосов
/ 07 июля 2010

Попробуйте использовать таймер

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

измените интервал и радиус.

0 голосов
/ 06 июля 2010

Вы можете создать схему разбрызгивания различной интенсивности, выбрав некоторое количество (связанное с желаемой интенсивностью и разбросом) полярных координат. Для этого определите случайную полярную координату (& rho ;, & theta;) для каждого образца с помощью:

& Rho; выборка из N (0, 1): Используйте Нормальное (гауссовское) распределение для расстояния от точного центра вашего рисунка распыления. Я не помню, есть ли в библиотеке .NET обычный генератор переменных. Если нет, вы можете создать его из генератора U (0, 1) .

& тэта; выборка из U (0, & pi;): Выборка углового компонента из Равномерное непрерывное распределение . Без потери производительности или универсальности вы можете вместо этого произвести выборку на U ( n & pi ;, m & pi;) для n <<i> m, но U (0, & pi;), вероятно, подойдет для того, что вам нужно.

Декартовы координаты каждого образца задаются как (T x + S x & cos; theta ;, T y + S y & rho; sin & theta;) где (T x , T y ) - центр рисунка распыления, который вы хотите создать; S x и S y - это коэффициенты спреда, которые вы хотите иметь в направлениях x и y соответственно.

0 голосов
/ 25 мая 2010

Я думаю, что трудно найти образец на C #. Ниже я представляю способ начать ваше путешествие по этому. Здесь я использую текстурную кисть.

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

}

как сказал Джесси, я думаю, вы должны найти алгоритм для распределения случайных пикселей.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...