刷子算法/褪色模式 - 需要建议

时间:2012-05-10 11:50:44

标签: c# algorithm design-patterns paint brush

我目前正在尝试创建一个简单的绘图工具,但我想出了一个问题,或者可能需要更多的建议。

我正在尝试创建一个画笔,因此当我绘制某个像素“中心”时,它也会绘制附近的像素。

例如:

1 pixel (center point)
[ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ]
[ ][ ][*][ ][ ]
[ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ]

2 pixel:
[ ][ ][ ][ ][ ]
[ ][ ][*][ ][ ]
[ ][*][*][*][ ]
[ ][ ][*][ ][ ]
[ ][ ][ ][ ][ ]

3 pixels:
[ ][ ][*][ ][ ]
[ ][*][*][*][ ]
[*][*][*][*][*]
[ ][*][*][*][ ]
[ ][ ][*][ ][ ]

此外,只有中心点应为100%的颜色。我怎样才能在以后采用原始颜色并略微淡化它。

示例:

1个像素,100%颜色

2个像素,中心点100%的颜色,附近的像素略微褪色或者可能(50%)

10像素,中心点100%的颜色,距离中心点最远的像素应该是原始颜色最褪色。

因此,计算附近颜色的算法和制作画笔图案的算法。

有什么建议吗?

色彩强度方法的实施(不起作用) 更新1:更改为Math.Pow(x,y) - 更慢,不起作用

    public static Color GetColorIntensity(Color c, double r, Point position, Point centerPosition)
    {
        double distance = Math.Sqrt((Math.Pow(position.X, 2)) + (Math.Pow(position.Y, 2)));
        double relative_distance = distance / r;
        double alpha = (1.0 - relative_distance);

        return Color.FromArgb((int)alpha, c.R, c.G, c.B);
    }

2 个答案:

答案 0 :(得分:3)

  1. 计算每个像素距画笔中心的距离。
  2. 指定从1.0(画笔中心)到0.0(画笔边缘)的透明度缩放。
  3. 如果你使用欧几里德距离d = sqrt(x^2 + y^2),你会得到一个圆形画笔。

    如果你使用出租车距离d = abs(x) + abs(y),你会得到一个菱形的刷子。

    这是Python的一个函数,用于计算相对于画笔中心坐标为x,y的像素的强度,画笔半径为ra = 1.0表示“完全不透明”,a = 0.0表示“完全透明”。

    def intensity(x,y,r):
        distance = sqrt( x**2 + y **2 )
        relative_distance = distance / r
        alpha = (1.0 - relative_distance)
        return alpha
    

    那里可能存在一个一个错误的错误(画笔将比r小一个像素),但你可以自己修复它。

答案 1 :(得分:1)

编辑#2 由于我需要解决谜题,我接受了其他人给出的答案,纠正了他们的数学错误,并提出了我认为你正在寻找的内容。

试试这个 我创建了一个新的Windows窗体应用程序,我添加了一个数字下拉(刷子大小),一个轨迹栏(淡化强度)和一个按钮,当你点击它开始从中心开始填充面板并向外移动时,刷子编号将是纯色,然后根据褪色强度,每一行向外都会越来越褪色。

 public Form1()
    {
        InitializeComponent();
    }
    Panel[,] pb = new Panel[9, 9];
    private void Form1_Load(object sender, EventArgs e)
    {
       //this is just to add the panels to the screen.  
       //We are using panels to simulate zoomed in pixels so we can see what is going on
        for (int y = 0; y < 9; y++)
            for (int x = 0; x < 9; x++)
            {
                pb[x, y] = new Panel();
                pb[x, y].BackColor = Color.MistyRose;
                pb[x, y].BorderStyle = BorderStyle.FixedSingle;
                pb[x, y].Size = new Size(20, 20);
                pb[x, y].Location = new Point(x * 20, y * 20);
                this.Controls.Add(pb[x,y]);
            }
    }
    private void button1_Click(object sender, EventArgs e)
    {
        DrawPixel(new Point(4, 4), (int)numericUpDown1.Value,trackBar1.Value+1);
    }

    public void DrawPixel(Point pixel, int radius,int intensity)
    {
        radius--;
        for (int y = 0; y <= 8; y++)
            for (int x = 0; x <= 8; x++)
            {
                //clears the screen before starting
                pb[x, y].BackColor = Color.White;
                //calculate the distance from the center pixel
                double Distance = Math.Sqrt( ((x-pixel.X)*(x-pixel.X) + (y-pixel.Y) *(y-pixel.Y))-radius*radius );
                //determine color intensity
                int alpha = (int)Distance <= 0 ? 255 : (int)Distance > intensity ? 0 : (int)(intensity - Distance) * 50 > 255 ? 255 : (int)(intensity - Distance) * 50;

                if (alpha>0)
                    pb[x, y].BackColor = Color.FromArgb(alpha, Color.Red);
            }
    }