Android如何用手指画一条平滑的线
http://marakana.com/tutorials/android/2d-graphics-example.html
我在下面使用这个例子。但是,当我在屏幕上移动手指的速度太快时,线条会变成单个点。
我不确定是否可以加快绘图速度。或者,我应该用一条直线连接最后两个点。这两种解决方案中的第二种似乎是一个不错的选择,除了非常快速地移动手指时,您会得到一条较长的直线段,然后是清晰的曲线。
如果还有其他解决方案,那么听听他们的声音会很棒。
感谢您的任何帮助。
-
正如你提到的,一个简单的解决方案是简单地将点与直线连接起来。这是这样做的代码:
public void onDraw(Canvas canvas) { Path path = new Path(); boolean first = true; for(Point point : points){ if(first){ first = false; path.moveTo(point.x, point.y); } else{ path.lineTo(point.x, point.y); } } canvas.drawPath(path, paint); }
确保将油漆从填充更改为描边:
paint = new Paint(Paint.ANTI_ALIAS_FLAG); paint.setStyle(Paint.Style.STROKE); paint.setStrokeWidth(2); paint.setColor(Color.WHITE);
另一个选择是使用quadTo方法将点与迭代连接:
public void onDraw(Canvas canvas) { Path path = new Path(); boolean first = true; for(int i = 0; i < points.size(); i += 2){ Point point = points.get(i); if(first){ first = false; path.moveTo(point.x, point.y); } else if(i < points.size() - 1){ Point next = points.get(i + 1); path.quadTo(point.x, point.y, next.x, next.y); } else{ path.lineTo(point.x, point.y); } } canvas.drawPath(path, paint); }
这仍然会导致一些尖锐的边缘。
如果你确实有野心,则可以开始如下计算三次样条:
public void onDraw(Canvas canvas) { Path path = new Path(); if(points.size() > 1){ for(int i = points.size() - 2; i < points.size(); i++){ if(i >= 0){ Point point = points.get(i); if(i == 0){ Point next = points.get(i + 1); point.dx = ((next.x - point.x) / 3); point.dy = ((next.y - point.y) / 3); } else if(i == points.size() - 1){ Point prev = points.get(i - 1); point.dx = ((point.x - prev.x) / 3); point.dy = ((point.y - prev.y) / 3); } else{ Point next = points.get(i + 1); Point prev = points.get(i - 1); point.dx = ((next.x - prev.x) / 3); point.dy = ((next.y - prev.y) / 3); } } } } boolean first = true; for(int i = 0; i < points.size(); i++){ Point point = points.get(i); if(first){ first = false; path.moveTo(point.x, point.y); } else{ Point prev = points.get(i - 1); path.cubicTo(prev.x + prev.dx, prev.y + prev.dy, point.x - point.dx, point.y - point.dy, point.x, point.y); } } canvas.drawPath(path, paint); }
另外,我发现你需要更改以下内容以避免重复的运动事件:
public boolean onTouch(View view, MotionEvent event) { if(event.getAction() != MotionEvent.ACTION_UP){ Point point = new Point(); point.x = event.getX(); point.y = event.getY(); points.add(point); invalidate(); Log.d(TAG, "point: " + point); return true; } return super.onTouchEvent(event); }
并将dx和dy值添加到Point类:
class Point { float x, y; float dx, dy; @Override public String toString() { return x + ", " + y; } }
这样可以产生平滑的线条,但有时必须使用循环将点连接起来。另外,对于较长的绘图会话,这将需要大量计算才能计算。
希望对你有所帮助。