我正在玩一个小涂料应用程序。我想创建不同的画笔提示(不仅仅是简单的线条)。基本思想是沿着鼠标移动重复(压印)刷尖。因为鼠标移动不会为鼠标移动的每个像素分派所需的事件。 我目前的方法是使用Bresenham算法来绘制我想要绘制的像素,然后在每个像素上标记刷尖。然而,这不是非常有效,因为刷尖例如是30×30px。我想以25%的画笔宽度标记,但我不知道这是如何以良好的方式完成的。我可以检测到距离并且仅在重新测试25%刷尖的距离之前进行标记。
还有其他想法如何实现一个考虑不规则鼠标事件并允许定义间距的冲压刷算法?
感谢阅读!
答案 0 :(得分:1)
回答有点迟,但如果有人在这里搜索答案,我是如何在我的代码中为java项目实现的。
步骤是画笔的百分比,所以如果它是20x20画笔,那么25步是5像素就是空格。
然后我从鼠标的最后和当前位置创建一个标准化的向量。
第一次点击first
之后。
当dist超过空间时,迭代器会处理所有距离,因为有时鼠标可以快速移动,因此有多个dib(或“戳”,dib是此域中的术语)
iter=space-remn
用于将其与之前的dib对齐。
使用vector*iter
添加的上一个位置让我们获得了dib的位置。
在我们绘制它们之后,所有这些都是重要的部分。
remn = dist-iter+space-remn;
剩余(remn)是从添加到初始阶段dist(距离)的先前过程中收集的。
要理解数学,请举例说明。
brush = 30x30,step = 25%,remn = 2.5,dist = 28.5(包括remn),space = 7.5(30 * 25/100)
下一个remn = 28.5(dist)-27.5(自检查以来最初的5个+ 7.5 * 3次(< 28.5-2.5)在更新后完成)+7.5(空格)-2.5(之前的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;
}
答案 1 :(得分:0)
Brasenham是一种近似算法,因为你已经近似而不是混叠,你可以更进一步......
稍微修改算法,您可以将画笔宽度作为参数(或者更好的是打印距离):
对计数器使用浮点数,如果像素不是正方形,则为您逐步执行的每个deltaY或deltaX添加不同的量,并考虑从x1,y1到x2,y2的向量方向以获得实际距离为每个像素添加。
非常简单的修改......