Немного опоздал с ответом, но если кто-то ищет ответы здесь, я реализую его в своем коде для проекта на Java.
Шаг - это процент кисти, поэтому, если это кисть 20x20, тогда 25шаг 5 пикселей, который является пробелом.
Затем я создаю нормализованный вектор из последней и текущей позиции мыши.
После first
, который является первым щелчком.Когда dist больше, чем пространство, создается итератор для обработки всего расстояния, потому что иногда мышь может двигаться быстро, поэтому в этом домене есть несколько dib (или «штампов», dibs)
iter=space-remn
предназначен для выравнивания его с предыдущей меткой.
Предыдущая позиция, добавленная с помощью vector*iter
, возвращает нам позицию для метки.
После того, как мы нарисуем их все, появляются важные биты.
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) выполняется после обновления iter) +7,5 (пробел) -2,5 (предыдущий остаток) = 6 пикселей </p>
Таким образом, мышь должна перемещаться 1,5пикселей для следующей метки, так как 6 пикселей уже пройдены.
В другом случае это evи более просто.
dist (в который уже добавлен remn) терпит неудачу в remn = dist.
Например, если у нас есть 2 пикселя с прошлого раза, мы добавляем расстояние, пройденное мышью, скажем 3пикселей, поэтому нам нужно проехать еще 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;
}