2011-05-23 65 views
2

我正在用小型涂料应用程序玩转。我想创建不同的笔刷提示(不仅是简单的线条)。基本想法是沿着鼠标移动重复(冲压)笔尖。由于鼠标移动不会为鼠标移动的每个像素分派所需的事件。 我目前的做法是使用Bresenham算法来绘制像素,然后在每个像素上涂刷画笔笔尖。然而这不是非常有效,因为刷子尖端例如是30x30像素。我想用刷子宽度的25%来印章,但我不知道这是如何以好的方式完成的。我可以检测距离并且只能印记直到25%刷子尖的距离发生反应。画笔冲压算法/技术

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

感谢您的阅读!

回答

0

的Brasenham是一个近似算法,因为你已经逼近,而不是混淆,你可以走那条路进一步...

随着你在哪里得到的刷宽度作为参数的算法的一个轻微的修改(或更好的是,所述打印距离):

  • 阈值是打印距离*矢量取向乘法器(45135225315度= SQRT(2))
  • 而不是在X,Y绘制像素 - >计算像素
  • 当在位置X pixelCount> =阈值打印刷,Y和复位pixelCount

使用的浮子用于计数器,并且如果像素不是正方形再加入不同量的为每个步骤通过移动deltaY或DELTAX,和考虑从x1,y1到x2,y2的矢量方向以获得每个像素添加的实际距离。

很简单...修改回答

+0

我想用刷子提示的百分比表示阈值。我正在考虑以像素为单位的刷子尖端宽度(==打印距离)作为阈值。但是,我很难理解为什么你将打印距离乘以矢量方向乘数(这是什么?)。你能解释一下吗?谢谢! – justin 2011-05-23 15:08:09

1

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

步骤是刷子的百分比,所以如果它是20x20刷,那么25步是5个像素,这是空间。

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

之后first这是第一次点击。 当DIST是更然后迭代器被制成处理所有的距离,因为有时鼠标可以快速移动,从而有多个DIBS的空间(或“标记”,DIBS是在本领域的术语)

iter=space-remn是将它与前面的dib对齐。

前一个位置加上vector*iter可以让我们得到dib的位置。

在我们绘制它们之后,所有重要的部分。

remn = dist-iter+space-remn;剩余(remn)是从前一个过程中收集的,并从初始阶段添加到dist(距离)。

要理解数学让我们举个例子。

刷= 30×,步长= 25%,remn = 2.5,DIST = 28.5(包括remn),空间= 7.5(30 * 25/100)

接下来remn = 28.5(DIST)-27.5( 5开始+ 7.5 * 3次,因为检查后(< 28.5-2.5)在更新之后完成)+7.5(空间)-2.5(先前剩余)= 6像素

因此,鼠标必须移动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; 
     }