的Andr​​oid如何绘制出流畅的线条下你的手指你的、线条、流畅、手指

2023-09-11 11:42:15 作者:刺猬的拥抱

http://marakana.com/tutorials/android/2d-graphics-example.html

我使用下面这个例子。但是,当我将我的手指过快在屏幕上线变为单个点。

I am using this example below. But when I move my fingers too fast across the screen the line turns to individual dots.

我不知道我是否能够加速绘图。或者我应该用直线连接这两个最后点。这两种解决方案的第二个似乎是个不错的选择,移动你的手指时,速度非常快,你将有一个直线长款则急转弯的除外。

I am not sure whether I can speed up the drawing. Or I should connect the two last points with a straight line. The second of these two solutions seems like a good option, except when moving your finger very fast you will have long sections of a straight line then sharp curves.

如果有任何其他的解决方案,这将是巨大的,听到他们的声音。

If there are any other solutions it would be great to hear them.

感谢提前任何帮助。

推荐答案

这是简单的解决方案,正如你所说,是简单地用直线连接点。这里的code这样做的:

An easy solution, as you mentioned, is to simply connect the points with a straight line. Here's the code to do so:

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);
}

请确保您填写更改您的油漆中风:

make sure you change your paint from fill to stroke:

paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(Color.WHITE);

另一种方法是用iterpolation使用quadTo方法连接点:

Another option is to connect the points with iterpolation using the quadTo method:

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);
}

这仍然导致了一些尖锐的边缘。

This still results in some sharp edges.

如果你真的雄心勃勃,你就可以开始计算的三次样条函数如下:

If you're really ambitious, you can start to calculate the cubic splines as follows:

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);
}

另外,我发现你需要改变以下,以避免出现重复的动作事件:

Also, I found that you needed to change the following to avoid duplicate motion events:

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类:

and add the dx & dy values to the Point class:

class Point {
    float x, y;
    float dx, dy;

    @Override
    public String toString() {
        return x + ", " + y;
    }
}

这会产生流畅的线条,但有时也有使用循环连接点。 此外,长期绘画会议,这成为计算密集型计算。

This produces smooth lines, but sometimes has to connect the dots using a loop. Also, for long drawing sessions, this becomes computationally intensive to calculate.

希望有所帮助......有趣的东西玩弄。

Hope that helps... fun stuff to play around with.

修改

我扔一起快速的项目演示这些不同的技术,其中包括Square的suggessted签名实现。享受: https://github.com/johncarl81/androiddraw

I threw together a quick project demonstrating these different techniques, including Square's suggessted signature implementation. Enjoy: https://github.com/johncarl81/androiddraw