画笔冲压算法/技术

| 我正在玩一个小的油漆应用程序。我想创建不同的“笔刷”提示(不仅是简单的线条)。基本思想是沿鼠标移动重复(标记)笔刷笔尖。因为鼠标移动不会为鼠标移动的每个像素调度所需的事件。 我当前的方法是使用Bresenham算法对要绘制的像素进行着色,然后在每个像素上标记画笔笔尖。但是,这不是很有效,因为画笔笔尖的大小例如为30x30像素。我想以笔刷宽度的25%进行印章,但是我不知道这是怎么做的。我可以检测到该距离,并且只有在达到25%的笔尖距离之前才盖章。 还有其他想法如何实现考虑不规则鼠标事件并允许定义间距的冲压画笔算法吗? 谢谢阅读!     
已邀请:
回答有点晚,但是如果有人在搜索答案,这就是我如何在我的Java项目代码中实现它。 该步骤是画笔的百分比,因此,如果它是20x20画笔,则25步是5像素,即空间。 然后,从鼠标的最后和当前位置创建归一化向量。 第一次点击“ 0”之后。 当dist大于空间时,将使迭代器处理所有距离,因为有时鼠标可以快速移动,因此存在多个dib(或\“ stamps \”,dibs是该域中的术语)
iter=space-remn
用于将其与上一个dib对齐。 先前加上
vector*iter
的位置将获得dib的位置。 在我们绘制它们之后,所有重要的部分都会出现。
remn = dist-iter+space-remn;
剩余(remn)是从前一个过程收集的,该过程与初始阶段的dist(距离)相加。 为了理解数学,让我们举个例子。 画笔= 30x30,步长= 25%,残差= 2.5,距离= 28.5(含残渣),间距= 7.5(30 * 25/100) 下一个remn = 28.5(dist)-27.5(5次初始+ 7.5 * 3次,因为更新iter之后检查(<28.5-2.5)完成)+7.5(space)-2.5(上一个remn)= 6像素 因此,由于已经移动了6个像素,因此鼠标必须为下一个dib移动1.5像素。 在其他情况下,它甚至更简单。 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;
        }
    
Brasenham是一种近似算法,因为您已经在近似而不是混叠,所以您可以进一步走下去... 稍加修改算法,即可将画笔宽度作为参数(或者更好的是,打印距离): 阈值是打印距离*矢量方向乘数(45,135,225,315度= sqrt(2)) 而不是在X,Y处绘制像素->计算像素 当pixelCount> =在X,Y位置的阈值打印笔刷并重置pixelCount时 使用浮点数作为计数器,如果像素不是正方形,则为您逐步经过的每个deltaY或deltaX添加不同的量,并考虑从x1,y1到x2,y2的向量方向以获得要添加的实际距离每个像素。 相当简单的修改...     

要回复问题请先登录注册