5

Hey I want to draw a line in different patterns by using canvas.

Any idea or suggestion are appreciate ..!!!!

Thanks in advance.

anddev
  • 3,144
  • 12
  • 39
  • 70

2 Answers2

3

You have to use Path.Docs say:

The Path class encapsulates compound (multiple contour) geometric paths consisting of straight line segments, quadratic curves, and cubic curves. ...

For example,you can extend a view and add touch event positions to a path in onTouchEvent(MotionEvent event) method of your view.Then you have to generate random positions correspond to newest touch event and add their to other instances of path.Finally in onDraw() method of your view,draw all paths.I hope this snippet help you to understand my idea:

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

In above code,I used two paths,but you can use three or more.Also the result,depends on your finger rate on the screen.For example:
enter image description here

or it may looks like this:

enter image description here

Edit:

Above class(NetCanvas) extends View,so you can create an instance of it and use that instance,like other views.For example,you can simply set an instance of it as ContentView of your Activity.Here I override onCreate() method of Activity:

@Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new NetCanvas(this));
    }

Although you can change NetCanvas to extend SurfaceView with some other changes.

hasanghaforian
  • 13,858
  • 11
  • 76
  • 167
1

I changed NetCanvas to draw a shape look like second image in your question:

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

Result depends on values of points_Num, first_Points_Num and order of points that are connected with lines in for loops:

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

You can change value of each variable or order of points to change result.Result may be looks like these:

enter image description here enter image description here

My idea is simple: Get points from path and connect them with lines.If you want to see more details in about getting points from path,that is done in getPoints() method,you can see this answer and it's references.I hope this help you.

Community
  • 1
  • 1
hasanghaforian
  • 13,858
  • 11
  • 76
  • 167