如何在android中连续绘制曲线?

时间:2015-10-05 03:12:37

标签: java android android-canvas

Curved Lines

你能帮我解决一下如何在android中连续绘制曲线吗?

3 个答案:

答案 0 :(得分:2)

如您所述,一个简单的解决方案是简单地用直线连接点。这是代码:

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

这仍然会产生一些尖锐的边缘。

如果你真的雄心勃勃,你可以按如下方式开始计算三次样条:

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&amp; dy值为Point类:

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

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

这会产生平滑的线条,但有时必须使用循环连接点。此外,对于长时间的绘图会话,计算量也会增加。

希望有助于...有趣的东西可以玩。

修改

我汇总了一个展示这些不同技术的快速项目,包括Square的suggessted签名实现。享受:https://github.com/johncarl81/androiddraw

答案 1 :(得分:0)

您可以使用图表库,例如mpandroidcharthttps://github.com/PhilJay/MPAndroidChart

在移除标签和网格时绘制线图。它应该适合你。

答案 2 :(得分:0)

public class MainActivity extends Activity {

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(com.example.lines.R.layout.activity_main);

    Paint paint = new Paint();
    paint.setColor(Color.RED);
    paint.setStyle(Paint.Style.STROKE);
    paint.setStrokeWidth(3);

    Bitmap bg = Bitmap.createBitmap(480,800, Bitmap.Config.ARGB_8888);
    Canvas can = new Canvas(bg);

    int left1 = 10;
    int top1 = 10;
    int right1 = 30;
    int bottom1 = 30;

    for(int j=0; j< 31; j++)
    {

        for(int i=0; i<23;i++)
        {
            RectF rectF1 = new RectF(left1,top1,right1,bottom1);
            can.drawArc(rectF1, 0, 180, false, paint);

            left1 = right1;
            right1 = left1+20;
        }
        System.out.println("\n");

        left1 = 10;
        top1 = bottom1 + 1;
        right1 = 30;
        bottom1 = 30+top1 - 6;

    }

    LinearLayout l1 = (LinearLayout)findViewById(com.example.lines.R.id.drawarea);
    l1.setBackgroundDrawable(new BitmapDrawable(bg));

}