1

I need to create shape as below using canvas in android.

enter image description here

Below is my code to achieve the same, I have drawn shape almost similar to it, but right side of curve is not taking shape when I pass points of e5 and e6 to draw arc using same function drawConcaveCurve as I did for e1 and e2. what I wanted to do here to bend path between e5 and e6?

public class HeapShape extends View {

ArrayList<Point> points = new ArrayList<>();

private final Paint mArcPaint = new Paint() {
    {
        setDither(true);
        setStyle(Paint.Style.STROKE);
        setStrokeCap(Paint.Cap.ROUND);
        setStrokeJoin(Paint.Join.ROUND);

        setColor(Color.BLUE);
        setStrokeWidth(5.0f);
        setAntiAlias(true);
    }
};

private final Paint mOvalPaint = new Paint() {
    {
        setStyle(Paint.Style.FILL);
        setColor(Color.TRANSPARENT);
    }
};


public HeapShape(Context context) {
    super(context);
}

public HeapShape(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public HeapShape(Context context, AttributeSet attrs, int defStyleAttr) {
    super(context, attrs, defStyleAttr);
}


@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);

    // TODO Auto-generated method stub
    super.onDraw(canvas);
    float width = (float) getWidth();
    float height = (float) getHeight();
    float radius;

    if (width > height) {
        radius = height / 8;
    } else {
        radius = width / 8;
    }


    float center_x, center_y;
    center_x = width / 2;
    center_y = height / 2;

    Path path = new Path();
    path.addCircle(center_x,
            center_y, radius,
            Path.Direction.CW);

    Paint paint = new Paint();
    paint.setStrokeWidth(5);
    paint.setStyle(Paint.Style.FILL);
    paint.setShader(new LinearGradient(getWidth(), getHeight(), getWidth(), getHeight(), Color.BLACK, Color.WHITE, Shader.TileMode.REPEAT));

    final RectF oval = new RectF();


    // left, top, right, bottom
    oval.set(center_x - radius,
            center_y - radius,
            center_x + radius,
            center_y + radius);
    canvas.drawArc(oval, 180, 180, false, paint);

    path.reset();

    // left point with 20 pixel upwards
    // point 1
    PointF e1 = new PointF();
    e1.set(center_x - radius, center_y);
    path.moveTo(e1.x, e1.y);
    // put point for our review
    canvas.drawCircle(e1.x, e1.y, 8, paint);

    // point 2
    PointF e2 = new PointF();
    e2.set(0, e1.y + 160);
    //path.lineTo(e2.x, e2.y);
    // draw concave curve
    path = drawConcaveCurve(e1, e2);
    // put point for our review
    canvas.drawCircle(e2.x, e2.y, 8, paint);

    // point 3
    PointF e3 = new PointF();
    e3.set(e2.x, e2.y + 80);
    path.lineTo(e3.x, e3.y);
    // put point for our review
    canvas.drawCircle(e3.x, e3.y, 8, paint);


    // point 4
    PointF e4 = new PointF();
    e4.set(e3.x + getWidth(), e3.y);
    path.lineTo(e4.x, e4.y);
    // put point for our review
    canvas.drawCircle(e4.x, e4.y, 8, paint);


    // point 5
    PointF e5 = new PointF();
    e5.set(e4.x, e4.y - 80);
    path.lineTo(e5.x, e5.y);
    // put point for our review
    canvas.drawCircle(e5.x, e5.y, 8, paint);


    // point 6
    PointF e6 = new PointF();
    e6.set(e5.x - 405, e5.y - 160);
    path.lineTo(e6.x, e6.y);
    // put point for our review

   // path = drawConcaveCurve(e6, e5);
    canvas.drawCircle(e6.x, e6.y, 8, paint);


    path.close();
    canvas.drawPath(path, paint);


}




private Path drawConcaveCurve(PointF e1, PointF e2) {

    int curveRadius = 180;
    final Path path = new Path();
    float midX            = e1.x + ((e2.x - e1.x) / 2);
    float midY            = e1.y + ((e2.y - e2.y) / 2);
    float xDiff         = midX - e1.x;
    float yDiff         = midY - e1.y;
    double angle        = (Math.atan2(yDiff, xDiff) * (180 / Math.PI)) - 90;
    double angleRadians = Math.toRadians(angle);
    float pointX        = (float) (midX + curveRadius * Math.cos(angleRadians));
    float pointY        = (float) (midY + curveRadius * Math.sin(angleRadians));

    path.moveTo(e1.x, e1.y);
    path.cubicTo(e1.x,e1.y,pointX, pointY, e2.x, e2.y);
    return path;
}


private Path drawConvaxCurve(PointF e1, PointF e2) {

    int curveRadius = 30;
    final Path path = new Path();
    float midX            = e1.x + ((e2.x - e1.x) / 2);
    float midY            = e1.y + ((e2.y - e2.y) / 2);
    float xDiff         = midX - e1.x;
    float yDiff         = midY - e1.y;
    double angle        = (Math.atan2(yDiff, xDiff) * (180 / Math.PI)) - 90;
    double angleRadians = Math.toRadians(angle);
    float pointX        = (float) (midX + curveRadius * Math.cos(angleRadians));
    float pointY        = (float) (midY + curveRadius * Math.sin(angleRadians));

    path.moveTo(e1.x, e1.y);
    path.cubicTo(e1.x,e1.y,pointX, pointY, e2.x, e2.y);
    return path;
}
}

The above code forming shape as below -

enter image description here

How do i make right side of the wing to be curve as same as left side. So kindly help me with your solutions and changes or modifications in my code. Thanks in advance.

BDL
  • 21,052
  • 22
  • 49
  • 55
chethan
  • 426
  • 5
  • 15
  • Find an answer [here](https://stackoverflow.com/questions/30073682/how-to-draw-bezier-curve-in-android). `Bezier Curve` is the keyword. – Phantômaxx Aug 23 '17 at 07:42
  • 1
    @ModularSynth, thanks for sharing this reference, i could construct code as per my requirement . – chethan Aug 23 '17 at 12:45

1 Answers1

1

I finally construct code. thanks for @ModularSynth sharing reference.

Here is the code what i exactly looking for :

public class DrawView extends View {

Paint paint;
Path path;

public DrawView(Context context) {
    super(context);
    init();
}

public DrawView(Context context, AttributeSet attrs) {
    super(context, attrs);
    init();
}

public DrawView(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
    init();
}

private void init() {
    paint = new Paint();

    paint.setStyle(Paint.Style.STROKE);

}

@Override
protected void onDraw(Canvas canvas) {


    int x = getWidth() / 2;
    int y = getHeight() / 2;
    path = new Path();
    paint.setColor(Color.RED);
    paint.setStrokeWidth(20);
    paint.setStyle(Paint.Style.FILL);
    paint.setShader(new LinearGradient(getWidth(), getHeight(), getWidth(), getHeight(), Color.BLACK, Color.WHITE, Shader.TileMode.REPEAT));


    // right panel
    path.moveTo(x, y);
    path.cubicTo(x + 200, y + 10, x + 20, y + 400, getWidth(), y + 400);
    //canvas.drawPath(path, paint);

    path.lineTo(getWidth(), y + 400 + 100);
    path.lineTo(0, y + 400 + 100);
    path.lineTo(0, y + 400);
    //canvas.drawPath(path, paint);

    // left panel
    //path.moveTo(x, y);
    path.cubicTo(x, y + 400, x - 200, y + 20 , x, y);
    canvas.drawPath(path, paint);

    canvas.drawPath(path, paint);

}
}
chethan
  • 426
  • 5
  • 15
  • here is the Github project link https://github.com/chethu/Animated-Vector-drawable-Path-Morphing – chethan Jul 21 '22 at 05:19