Как я могу моделировать брызги как краска окон? я думаю это случайные точки формирования данных, каково Ваше мнение?
Да, я бы сказал, что он раскрашивает случайные пиксели в пределах определенного радиуса от точки выбора. Также, вероятно, существует временная задержка между окрашиванием одного пикселя и другого, потому что сегодня машины достаточно быстрые, чтобы иметь возможность раскрасить каждый возможный пиксель (пока радиус небольшой), прежде чем вы сможете отпустить кнопку мыши.
Кроме того, я думаю, что алгоритм, который использует Paint, может выбрать пиксель для рисования, даже если он уже был нарисован, поскольку иногда вы можете получить нарисованный круг с несколькими неокрашенными пикселями внутри.
Узор для аэрозольной краски будет полуслучайным. Если вы достанете баллончик Krylon и медленно проведете линию на стене, то в итоге получите широкую сплошную линию, переходящую в фон с градиентом по краям. Если распылять краску в одном месте в течение десяти секунд, вы получите большую точку в центре, в которой цвет полностью насыщен, с радиальным градиентом к фону.
Итак, ваши переменные для моделирования включают:
Думаю, трудно найти пример на 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!");
}
}
как сказал Джесси, я думаю, вам нужно найти алгоритм для разбрасывания случайных пикселей.
Вы получили ряд ответов, указывающих на правильное направление, в котором следует начать работу с пользовательским интерфейсом эффекта спрея. Основываясь на вашем ответе на мой комментарий, вам также понадобится алгоритм для генерации случайных точек в радиусе.
Есть несколько способов сделать это, и, вероятно, наиболее очевидным будет использование полярных координат для выбора случайной точки и последующего преобразования полярных координат в декартовы координаты (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));
}
}
}
Попробуйте использовать таймер
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;
}
}
, пожалуйста, измените Интервал и радиус.
Вы можете создать рисунок распыления различной интенсивности, выбрав некоторое количество (связанное с желаемой интенсивностью и разбросом) полярных координат. Для этого определите случайную полярную координату (ρ, θ) для каждой выборки следующим образом:
ρ выборка из N (0, 1): Используйте нормальное (гауссово) распределение для расстояние от точного центра вашей формы распыления. Я не помню, есть ли в библиотеке .NET нормальный генератор переменных. Если нет, вы можете создать его из генератора U (0, 1) .
θ, взятый из U (0, π): Пример угловой составляющей из Uniform Continuous Distribution . Без потери производительности или общности, вместо этого можно было бы выполнить выборку на U ( n π, m π) для n < m , но U (0, π), вероятно, подойдет для того, что вам нужно.
Декартовы координаты каждой выборки выражаются как (T x + S x ρ cos θ, T y + S y ] ρ sin θ) где (T x , T y ) - центр рисунка распыления, который вы хотите создать; S x и S y - это коэффициенты распространения, которые вы хотите иметь в направлениях x и y соответственно.