首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >画笔冲压算法/技术

画笔冲压算法/技术
EN

Stack Overflow用户
提问于 2011-05-23 18:01:06
回答 2查看 1.7K关注 0票数 2

我正在摆弄一个小的绘画应用程序。我想创建不同的笔刷提示(不仅仅是简单的线条)。基本思想是沿鼠标移动重复(盖章)画笔笔尖。因为鼠标移动不会为鼠标移动的每个像素分派所需的事件。我目前的方法是使用Bresenham算法对我想要绘制的像素进行定位,然后在每个像素上标记画笔笔尖。然而,这并不是很有效,因为画笔笔尖例如是30x30像素。我想按笔刷宽度的25%盖章,但我不知道怎么做才好。我可以检测到距离,只有在达到25%的刷尖距离时才会盖章。

如何实现一个考虑不规则鼠标事件并允许定义间距的冲压画笔算法?

感谢您的阅读!

EN

回答 2

Stack Overflow用户

发布于 2012-06-23 21:36:22

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

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

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

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

iter=space-remn用于将其与前一个dib对齐。

添加了vector*iter的前一个位置得到了dib的位置。

在我们把它们都画出来之后,就是重要的部分了。

remn = dist-iter+space-remn;余数(Remn)是从添加到距离初始阶段的dist(距离)的先前过程中收集的。

为了理解数学,让我们来看一个例子。

刷子= 30x30,步长= 25%,remn=2.5,dist =28.5(含remn),间距= 7.5(30*25/100)

下一个remn =28.5(Dist)-27.5(自在iter更新后执行检查(<28.5-2.5)以来的5个initially+7.5*3次数)+7.5(空间)-2.5(上一个remn) =6像素

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

在else的情况下,它甚至更简单。

dist(已经添加了remn ) remn=dist失败。

例如,如果上一次我们有2个像素,我们加上鼠标移动的距离,比如说3个像素,那么我们需要在下一个dib中额外移动2.5个像素。

代码语言:javascript
运行
复制
    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;
        }
票数 2
EN

Stack Overflow用户

发布于 2011-05-23 18:27:25

Brasenham是一种近似算法,既然你已经在近似而不是走样,你可以走得更远……

稍微修改一下算法,将画笔宽度作为参数(或者更好的是,打印距离):

  • threshold是打印距离*矢量方向乘数(45,135,225,315度= sqrt(2))
  • instead of drawing Pixels at X,Y -> count pixels
  • when pixelCount >= threshold print
  • at location X,Y-> reset pixelCount

使用浮点数作为计数器,如果像素不是正方形,则为您所遍历的每个deltaY或deltaX添加不同的量,并考虑从x1,y1到x2,y2的向量方向,以获得要为每个像素添加的实际距离。

非常简单的修改。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6095636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档