2011-05-23 74 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; 
     }