2010-05-25 36 views
6

Làm thế nào tôi có thể mô phỏng một loại phun như sơn cửa sổ? tôi nghĩ rằng nó tạo ra điểm ngẫu nhiên, ý kiến ​​của bạn là gì?Mô phỏng phun

+0

Đây có phải là cách tạo phun bằng C# cụ thể không? Nếu không, tại sao thẻ này được gắn thẻ "C#"? –

+0

Có điều này là về việc tạo ra một phun trong C# –

+0

Làm việc cho tôi, sau đó. Đôi khi hơi khó hiểu khi một câu hỏi có một thẻ, nhưng câu hỏi thực tế có vẻ rất chung chung và không thực sự đề cập đến bất kỳ liên quan nào đến thẻ. Cảm ơn, Hesam. –

Trả lời

5

Có, tôi sẽ nói nó màu sắc các pixel ngẫu nhiên trong một bán kính nhất định của điểm lựa chọn. Cũng có thể có sự chậm trễ thời gian giữa màu của một pixel và điểm ảnh khác, bởi vì các máy ngày nay đủ nhanh để có thể tô màu mọi pixel có thể (miễn là bán kính nhỏ) trước khi bạn có thể thả nút chuột.

Ngoài ra, tôi nghĩ thuật toán mà Paint sử dụng có thể chọn một pixel để vẽ ngay cả khi nó đã được vẽ, vì đôi khi bạn có thể kết thúc với một vòng tròn sơn với một vài điểm ảnh không sơn bên trong.

+0

'Cũng có thể có sự chậm trễ thời gian giữa màu của một điểm ảnh và điểm ảnh khác - nó chỉ vẽ nếu con chuột di chuyển giữa một khung hình sang khung hình tiếp theo. –

+1

@BlueRaja, tôi vừa mở mspaint và giữ nút chuột xuống. Vòng tròn chầm chậm lấp đầy mà không di chuyển chuột của tôi. FYI. –

+0

Ngoài ra, hãy nhớ rằng nó phun với một yếu tố minh bạch. Và nếu một pixel bị phun lên một pixel khác thì độ trong suốt sẽ trở nên mờ đục hơn. Well Paint không làm điều này, nhưng Photoshop – Icemanind

-1

Tôi nghĩ rất khó để tìm mẫu trên C#. Dưới đây tôi trình bày một cách để bắt đầu cuộc hành trình của bạn về điều này. Ở đây tôi đang sử dụng một bàn chải kết cấu.

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

} 

như Jesse đã nói, tôi nghĩ bạn nên tìm một thuật toán để truyền các pixel ngẫu nhiên.

3

Mẫu sơn phun sẽ là bán ngẫu nhiên. Nếu bạn lấy ra một lon Krylon và từ từ phun một đường thẳng lên tường, bạn sẽ kết thúc với một đường thẳng rộng, mờ dần về phía sau với một gradient xung quanh các cạnh. Phun vào một chỗ trong mười giây, và bạn sẽ có một chấm lớn ở trung tâm, trong đó màu sắc được bão hòa hoàn toàn, với một gradient xuyên tâm nền.

Somali biến của bạn cho mô phỏng bao gồm:

  • Thời gian giữ "phun" (nút chuột)
  • chuyển động của "có thể" (chuột)
  • Tốc độ của "có thể" (di chuyển chậm tạo ra một dòng ánh sáng, không bão hòa. Chuyển động chậm tạo thành một đường kẻ đậm, bão hòa với một gradient)
  • mô hình lây lan: là bình xịt được tập trung như một chiếc airbrush hay lớn như bình phun?
  • "Khoảng cách": Cách "phun" từ "canvas" bao xa?
2

Bạn đã nhận được một số câu trả lời chỉ cho bạn đúng hướng để bắt đầu xử lý trải nghiệm người dùng về hiệu ứng phun. Dựa trên phản ứng của bạn đối với nhận xét của tôi, bạn cũng cần một thuật toán để tạo các điểm ngẫu nhiên trong bán kính.

Có một số cách để thực hiện điều này và có lẽ rõ ràng nhất là sử dụng polar coordinates để chọn điểm ngẫu nhiên và sau đó chuyển tọa độ cực thành toạ độ (x, y) để hiển thị pixel. Đây là một ví dụ đơn giản về cách tiếp cận này. Để giữ cho mọi thứ đơn giản, tôi vừa vẽ một hình elip 1x1 đơn giản cho mỗi điểm.

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

Ngoài ra, bạn ngẫu nhiên có thể chọn x, y tọa độ từ hình chữ nhật phù hợp với vòng tròn xịt và sử dụng r phương trình đường tròn^2 = x^2 + y^2 kiểm tra các điểm để xác định xem nó nằm bên trong vòng tròn, nếu bạn chọn ngẫu nhiên một điểm khác và kiểm tra lại cho đến khi bạn có một điểm nằm trong vòng tròn. Đây là một mẫu nhanh của phương pháp này

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

Bạn có thể tạo một mẫu phun cường độ khác nhau bằng cách lấy mẫu một số (liên quan đến cường độ và độ lan truyền mong muốn) của tọa độ cực.Để làm điều này, xác định một coordiate ngẫu nhiên cực (ρ, θ) cho mỗi mẫu bằng cách:

ρ lấy mẫu từ N (0, 1): Sử dụng một Normal (Gaussian) distribution cho khoảng cách từ trung tâm chính xác của mô hình phun của bạn. Tôi không nhớ nếu có một máy phát variate bình thường trong thư viện .NET. Nếu không có, bạn có thể create one from a U(0, 1) generator.

θ lấy mẫu từ U (0, π): Lấy mẫu thành phần góc từ Uniform Continuous Distribution. Không mất tính tổng hiệu suất hoặc tính tổng quát, bạn thay vì có thể lấy mẫu trên U ( n π, m π) cho n < m, nhưng U (0, π) có lẽ sẽ tốt cho những gì bạn cần.

Các tọa độ Descartes của mỗi mẫu được đưa ra bởi (T x + S x ρ cos θ, T y + S y ρ tội θ) nơi (T x, T y) là trung tâm của mẫu phun mà bạn muốn tạo; S x và S y là các yếu tố lan truyền bạn muốn có theo hướng x và y tương ứng.

0

Hãy thử sử dụng bộ đếm thời gian

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

xin vui lòng thay đổi Interval và bán kính.