algorithm - 画笔冲压算法/技术

标签 algorithm paint

我正在玩一个小的油漆应用程序。我想创建不同的画笔提示(不仅仅是简单的线条)。基本思想是沿着鼠标移动重复(冲压)画笔 Nib 。因为鼠标移动不会为鼠标移动的每个像素分派(dispatch)所需的事件。 我目前的方法是使用 Bresenham 算法获取我想要绘制的像素,然后在每个像素上标记画笔 Nib 。然而,这不是很有效,因为画笔 Nib 是例如 30x30 像素。我想在画笔宽度的 25% 处进行标记,但我不知道这是如何以一种好的方式完成的。我可以检测到距离并且只盖章直到 25% 的刷尖距离被重新标记。

关于如何实现考虑不规则鼠标事件并允许定义间距的冲压画笔算法的任何其他想法?

感谢阅读!

最佳答案

回答有点晚了,但如果有人在这里搜索答案,我是如何在我的代码中为一个 java 项目实现它的。

步长是画笔的百分比,所以如果它是 20x20 画笔,那么 25 步长是 5 个像素,也就是空间。

然后我根据鼠标的最后位置和当前位置创建一个归一化向量。

first 之后,这是第一次点击。 当 dist 大于空间时,迭代器将处理所有距离,因为有时鼠标可以快速移动,因此有多个 dibs(或“邮票”,dibs 是该域中的术语)

iter=space-remn 是为了和之前的dib对齐。

vector*iter 添加的先前位置为我们提供了 dib 的位置。

在我们绘制完所有这些之后,重要的部分就出现了。

remn = dist-iter+space-remn; Remainder(remn) 是从初始阶段添加到 dist(distance) 的前一个过程中收集的。

为了理解数学,让我们举个例子。

brush = 30x30, step = 25%, remn=2.5, dist = 28.5(including remn), space = 7.5(30*25/100)

下一个remn = 28.5(dist)-27.5(初始为5+7.5*3次自检查(<28.5-2.5)在iter更新后完成) +7.5(space)-2.5(previous remn) = 6像素

因此鼠标必须为下一个 dib 移动 1.5 像素,因为已经移动了 6 个像素。

在其他情况下,它甚至更直接。

dist(已经添加了 remn)无法满足 remn=dist。

例如,如果我们从上次开始有 2 个像素,我们加上鼠标移动的距离,比如说 3 个像素,所以我们需要为下一个 dib 再移动 2.5 个像素。

    int size =(Integer) tool.getAttribute("size");
        int step = (Integer) tool.getAttribute("step");
        double space = size*step/100.0f; //what is actualy need for the check algorithm for the step rate to work
        double dist = Point.distance(pZero.getX(),pZero.getY(),last.getX(),last.getY());
        int bleed = (int) (size/tilemap[0].getWidth()+size/tilemap[0].getHeight());
        Point2D.Double vec = new Point2D.Double(pZero.getX()-last.getX(),pZero.getY()-last.getY());
        vec.x /= dist;
        vec.y /= dist;
        dist+=remn;
        if(first){
            //System.out.println("First ");
            for(int y=0; y < tilesHigh; ++y) {
                for(int x=0; x < tilesWide; ++x) {

                    int pos = x+y*tilesWide;
                    // This should never exceed tilemap.length.
                    BufferedImage tile = tilemap[pos];
                    //tool.operate(tile.getGraphics(), new Point(pZero.x-x*tile.getWidth(), pZero.y-y*tile.getHeight()));
                    tool.operate(tile.getGraphics(), tilemapPointToTilePoint(pZero, pos));

                }
            }
            first = false;
        }else {
            if(dist>=space){//check to see if the mouse distance is enoght for a step(space)
                iter=space-remn;
                //test=0;
                //System.out.println("pZero="+pZero);
                while(iter<dist-remn){//fills the gap between with at the rate of step(space),if you move the mouse fast you use to get those
                    //do stuff
                    pZero.x =(int) Math.round(last.x + (vec.x*iter));
                    pZero.y =(int) Math.round(last.y + (vec.y*iter));
                    //int pos = xyToIndex(pZero.x, pZero.y);
                    //test++;
                    //System.out.println("iter = "+iter+" remn="+remn+" space="+space);
                    //System.out.println("pIter="+pZero);
                    //System.out.println("Second ");

                    for(int y=0; y < tilesHigh; ++y) {//bleed
                        for(int x=0; x < tilesWide; ++x) {
                            int pos = x+y*tilesWide;
                            // This should never exceed tilemap.length.
                            BufferedImage tile = tilemap[pos];
                            //tool.operate(tile.getGraphics(), new Point(pZero.x-x*tile.getWidth(), pZero.y-y*tile.getHeight()));
                            tool.operate(tile.getGraphics(), tilemapPointToTilePoint(pZero, pos));
                        }
                    }
                    iter += space;
                }
                //System.out.println("last = "+last);
                //System.out.println("test="+test);
                remn = dist-iter+space-remn;
            }else remn = dist;
        }

关于algorithm - 画笔冲压算法/技术,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6095636/

相关文章:

java - 线程中的实例化组件不会重新绘制到 Java 中的 JFrame 中

java - 一个简单的 slider 游戏(游戏逻辑和绘制组件方法)

algorithm - 在分布式哈希表中的节点连接期间优化键空间分区

php - 如何检查句子中是否存在关键字集?

c# - 矩阵行列式

algorithm - 二维矩阵中的最长递增子序列。

c++ - 此人如何使用 Microsoft Paint 编码 "Hello World"?

qt - 如何在Qt QSlider上绘制图片而不是 slider ?

java - 在 JavaFX Canvas 上应用 DropShadow 作为单独的层

string - 如何将字符串格式化为电话号码 kotlin 算法