如何使用画布绘制不同图案的线条?

时间:2013-01-08 07:03:17

标签: android android-canvas

嘿我想用画布画出不同图案的线条。

任何想法或建议都很高兴.. !!!!

提前致谢。

2 个答案:

答案 0 :(得分:3)

您必须使用 Path .Docs说:

  

Path类封装了复合(多个轮廓)几何   由直线段,二次曲线和   三次曲线。 ...

例如,您可以扩展view并将触摸事件位置添加到视图的path方法中的onTouchEvent(MotionEvent event)。然后您必须生成与最新触摸事件对应的随机位置并将它们添加到路径的其他实例。最后在视图的onDraw()方法中,绘制所有路径。我希望此片段可以帮助您理解我的想法:

public class NetCanvas extends View {

    private static final double MAX_DIFF = 15;
    Path path0 = new Path();
    Path path = new Path();
    private Paint p0;
    private Paint p;

    public NetCanvas(Context context) {
        super(context);
        p0 = new Paint();
        p0.setShader(new LinearGradient(0, 0, 230, getHeight(), Color.GREEN,
                Color.RED, Shader.TileMode.CLAMP));
        p0.setStyle(Style.STROKE);

        p = new Paint();
        p.setShader(new LinearGradient(0, 0, 230, getHeight(), Color.BLUE,
                Color.MAGENTA, Shader.TileMode.CLAMP));
        p.setStyle(Style.STROKE);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float x0 = event.getX();
        float y0 = event.getY();
        float x = generateFloat(event.getX());
        float y = generateFloat(event.getY());

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            path0.moveTo(x0, y0);
            path0.lineTo(x0, y0);

            path.moveTo(x, y);
            path.lineTo(x, y);
        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            path0.lineTo(x0, y0);

            path.lineTo(x, y);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            path0.lineTo(x0, y0);

            path.lineTo(x, y);
        }
        invalidate();
        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawPath(path0, p0);
        canvas.drawPath(path, p);
    }

    private float generateFloat(Float f){
        double d = (Math.signum(2*Math.random() - 1)) * Math.random() * MAX_DIFF;
        return (float) (f + d);
    }
}

在上面的代码中,我使用了两个path,但你可以使用三个或更多 。还有结果,取决于你的手指率屏幕。例如:
enter image description here

或者看起来像这样:

enter image description here

修改

上面的类(NetCanvas)扩展View,因此您可以像其他视图一样创建它的实例并使用该实例。例如,您只需将其实例设置为{{ 1}}你的Activity.Here我覆盖了ContentView Activity的方法:

onCreate()

虽然您可以更改@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(new NetCanvas(this)); } 以扩展NetCanvas并进行其他更改。

答案 1 :(得分:1)

我更改NetCanvas以在您的问题中将形状看作第二张图片:

public class NetCanvas1 extends View {

    Path path0 = new Path();
    private Paint p0;
    private int points_Num = 20;
    private int first_Points_Num = 5;

    public NetCanvas1(Context context) {
        super(context);
        p0 = new Paint();
        p0.setShader(new LinearGradient(0, 0, 230, getHeight(), Color.GREEN,
                Color.RED, Shader.TileMode.CLAMP));
        p0.setStyle(Style.STROKE);

    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float x0 = event.getX();
        float y0 = event.getY();

        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            path0.moveTo(x0, y0);
            path0.lineTo(x0, y0);

        } else if (event.getAction() == MotionEvent.ACTION_MOVE) {
            path0.lineTo(x0, y0);
        } else if (event.getAction() == MotionEvent.ACTION_UP) {
            path0.lineTo(x0, y0);
            invalidate();
        }
        return true;
    }

    @Override
    public void onDraw(Canvas canvas) {
        canvas.drawPath(path0, p0);
        FlaotPoint[] pointArray = getPoints();
        try {
            for (int i = 0; i < first_Points_Num; i++) {
                for (int j = i; j < pointArray.length; j++) {
                    canvas.drawLine(pointArray[i].getX(), pointArray[i].getY(),
                            pointArray[j].getX(), pointArray[j].getY(), p0);
                }
            }
            path0.reset();
        } catch (Exception e) {
        }
    }

    private FlaotPoint[] getPoints() {
        FlaotPoint[] pointArray = new FlaotPoint[points_Num];
        PathMeasure pm = new PathMeasure(path0, false);
        float length = pm.getLength();
        float distance = 0f;
        float speed = length / points_Num;
        int counter = 0;
        float[] aCoordinates = new float[2];

        while ((distance < length) && (counter < points_Num)) {
            // get point from the path
            pm.getPosTan(distance, aCoordinates, null);
            pointArray[counter] = new FlaotPoint(aCoordinates[0],
                    aCoordinates[1]);
            counter++;
            distance = distance + speed;
        }

        return pointArray;
    }

    class FlaotPoint {
        float x, y;

        public FlaotPoint(float x, float y) {
            this.x = x;
            this.y = y;
        }

        public float getX() {
            return x;
        }

        public float getY() {
            return y;
        }
    }
}

结果取决于points_Numfirst_Points_Num的值以及与for循环中的行相关联的点的顺序:

for (int i = 0; i < first_Points_Num; i++) {
                for (int j = i; j < pointArray.length; j++) {
                    canvas.drawLine(pointArray[i].getX(), pointArray[i].getY(),
                            pointArray[j].getX(), pointArray[j].getY(), p0);
                }
            }

您可以更改每个变量的值或点的顺序以更改结果。结果可能如下所示:

enter image description here enter image description here

我的想法很简单: 从路径获取积分并将其与行 相关联。如果您想查看有关从路径获取积分的更多详细信息,请执行以下操作: getPoints()方法,您可以看到 this answer 及其引用。我希望这对您有所帮助。