如何在 android canvas 中快速移动手指时使用路径绘制画笔或形状(当用户快速移动手指时生成缺失点)
how to draw brushes or shape using path when moving finger fast in andorid canvas (generate missing point when user move finger fast)
我真的很困惑如何在 android 中绘制专业画笔,当用户在屏幕上移动手指时,我使用路径绘制圆圈,但当用户移动手指缓慢时,圆圈数量增加,当用户移动时finger fast 圆圈的数量非常少,假设用户移动它的手指非常快,那条路径上只会有 6 7 个圆圈,但如果用户缓慢移动手指,路径上会有 30/40 或更多的圆圈,这看起来非常buggy,有没有可能是快速移动手指存储的点数少?但是如果我谈论线条,canvas 上的线条在用户快速或缓慢地移动手指时完美绘制,我在下面分享我的代码
private void DrawCircleBrush(List<PointF> points) {
PointF p1 = points.get(0);
PointF p2 = points.get(1);
Path path = new Path();
path.moveTo(p1.x, p1.y);
for (int i = 1; i < points.size(); i++) {
int rc = (int) (20 +(this.paintStrokeWidth/5));
path.addCircle(p1.x, p1.y, (float) rc, Path.Direction.CCW);
}
this.invalidate();
}
我像这样在 action_move 上调用 DrawCircleBrush Fucnion
path.reset();
points.add(new PointF(x, y));
DrawCircleBrush(points);
您可以在附图中看到快速移动和慢速移动手指的区别。
你可以在这张照片中看到我想要实现的目标,因为当我快速或缓慢移动手指时,此应用程序中的画笔绘制相同,
好的,我终于找到了解决办法。
这就是我得到所有分数的方式,请注意,这是一个称为 Bresenham 直线算法的定理,它只适用于整数,
这就是我得到所有要点的方式,快速或慢速移动手指点将始终相同:D
//x0,y0 , is the starting point and x1,y1 are current points
public List<PointF> findLine( int x0, int y0, int x1, int y1)
{
List<PointF> line = new ArrayList<PointF>();
int dx = Math.abs(x1 - x0);
int dy = Math.abs(y1 - y0);
int sx = x0 < x1 ? 1 : -1;
int sy = y0 < y1 ? 1 : -1;
int err = dx-dy;
int e2;
while (true)
{
line.add(new PointF(x0,y0));
if (x0 == x1 && y0 == y1)
break;
e2 = 2 * err;
if (e2 > -dy)
{
err = err - dy;
x0 = x0 + sx;
}
if (e2 < dx)
{
err = err + dx;
y0 = y0 + sy;
}
}
return line;
}
我是如何为我的画笔使用这个功能的,
//radius of circle
int rc = (int) (20 +(this.paintStrokeWidth/5));
//getting the points of line
List<PointF> pointFC =findLine((int)this.startX,(int) this.startY,(int) x,
(int) y);
//setting the index of first point
int p1 = 0;
//will check if change occur
boolean change = false;
for(int l=1; l<pointFC.size(); l++){
//getting distance between two pints
float d = distanceBetween(pointFC.get(p1),pointFC.get(l));
if(d>rc){
// we will add this point for draw
//point is a list of PointF //declared universally
points.add(new PointF(pointFC.get(l).x,pointFC.get(l).y));
we will change the index of last point
p1 = l-1;
change = true;
}
}
if(points.size() >0){
path.reset();
DrawCircleBrush(points);
}
if(change){
we will cahnge the starts points, //set them as last drawn points
this.startX = points.get(points.size()-1).x;
this.startY = points.get(points.size()-1).y;
}
//Distance betwenn points
private float distanceBetween(PointF point1,PointF point2) {
return (float) Math.sqrt(Math.pow(point2.x - point1.x, 2) +
Math.pow(point2.y - point1.y, 2));
}
//this is how im drawing my circle brush
private void DrawCircleBrush(List<PointF> points) {
Path path = this.getCurrentPath();
path.moveTo(points.get(0).x, points.get(0).y);
for (int i = 1; i < points.size(); i++) {
PointF pf = points.get(i);
int rc = (int) (20 +(this.paintStrokeWidth/5));
path.addCircle(pf.x, pf.y, (float) rc, Path.Direction.CCW);
}
}
结果:手指移动快慢刷都一样
检查 here
中的“colored_pixels”
我真的很困惑如何在 android 中绘制专业画笔,当用户在屏幕上移动手指时,我使用路径绘制圆圈,但当用户移动手指缓慢时,圆圈数量增加,当用户移动时finger fast 圆圈的数量非常少,假设用户移动它的手指非常快,那条路径上只会有 6 7 个圆圈,但如果用户缓慢移动手指,路径上会有 30/40 或更多的圆圈,这看起来非常buggy,有没有可能是快速移动手指存储的点数少?但是如果我谈论线条,canvas 上的线条在用户快速或缓慢地移动手指时完美绘制,我在下面分享我的代码
private void DrawCircleBrush(List<PointF> points) {
PointF p1 = points.get(0);
PointF p2 = points.get(1);
Path path = new Path();
path.moveTo(p1.x, p1.y);
for (int i = 1; i < points.size(); i++) {
int rc = (int) (20 +(this.paintStrokeWidth/5));
path.addCircle(p1.x, p1.y, (float) rc, Path.Direction.CCW);
}
this.invalidate();
}
我像这样在 action_move 上调用 DrawCircleBrush Fucnion
path.reset();
points.add(new PointF(x, y));
DrawCircleBrush(points);
您可以在附图中看到快速移动和慢速移动手指的区别。
你可以在这张照片中看到我想要实现的目标,因为当我快速或缓慢移动手指时,此应用程序中的画笔绘制相同,
好的,我终于找到了解决办法。 这就是我得到所有分数的方式,请注意,这是一个称为 Bresenham 直线算法的定理,它只适用于整数, 这就是我得到所有要点的方式,快速或慢速移动手指点将始终相同:D
//x0,y0 , is the starting point and x1,y1 are current points
public List<PointF> findLine( int x0, int y0, int x1, int y1)
{
List<PointF> line = new ArrayList<PointF>();
int dx = Math.abs(x1 - x0);
int dy = Math.abs(y1 - y0);
int sx = x0 < x1 ? 1 : -1;
int sy = y0 < y1 ? 1 : -1;
int err = dx-dy;
int e2;
while (true)
{
line.add(new PointF(x0,y0));
if (x0 == x1 && y0 == y1)
break;
e2 = 2 * err;
if (e2 > -dy)
{
err = err - dy;
x0 = x0 + sx;
}
if (e2 < dx)
{
err = err + dx;
y0 = y0 + sy;
}
}
return line;
}
我是如何为我的画笔使用这个功能的,
//radius of circle
int rc = (int) (20 +(this.paintStrokeWidth/5));
//getting the points of line
List<PointF> pointFC =findLine((int)this.startX,(int) this.startY,(int) x,
(int) y);
//setting the index of first point
int p1 = 0;
//will check if change occur
boolean change = false;
for(int l=1; l<pointFC.size(); l++){
//getting distance between two pints
float d = distanceBetween(pointFC.get(p1),pointFC.get(l));
if(d>rc){
// we will add this point for draw
//point is a list of PointF //declared universally
points.add(new PointF(pointFC.get(l).x,pointFC.get(l).y));
we will change the index of last point
p1 = l-1;
change = true;
}
}
if(points.size() >0){
path.reset();
DrawCircleBrush(points);
}
if(change){
we will cahnge the starts points, //set them as last drawn points
this.startX = points.get(points.size()-1).x;
this.startY = points.get(points.size()-1).y;
}
//Distance betwenn points
private float distanceBetween(PointF point1,PointF point2) {
return (float) Math.sqrt(Math.pow(point2.x - point1.x, 2) +
Math.pow(point2.y - point1.y, 2));
}
//this is how im drawing my circle brush
private void DrawCircleBrush(List<PointF> points) {
Path path = this.getCurrentPath();
path.moveTo(points.get(0).x, points.get(0).y);
for (int i = 1; i < points.size(); i++) {
PointF pf = points.get(i);
int rc = (int) (20 +(this.paintStrokeWidth/5));
path.addCircle(pf.x, pf.y, (float) rc, Path.Direction.CCW);
}
}
结果:手指移动快慢刷都一样
检查 here
中的“colored_pixels”