Android: how to draw path without overlapping using canvas? - android

I have a 3x3 game board and I need to draw a path from check to check.
game board:
Using below functions I can draw path with center point of checks.
Canvas function:
drawPath(Path path, Paint paint)
Path function:
lineTo(float x, float y)
draw path like:
However, path are overlapped if path passes through a point over one time.
like this(left: current, right: expected), overlapped at corner:
and this(left: current, right: expected), overlapping lines and corner:
Is there a library or technique to due with this kind of problem(draw the right non-overlapped path)?

Related

How to allow users to draw only within a specified area in Android?

In my Android Project I have a drawView which user can draw.
And it draw a body shape by using x Coordinates, y Coordinates and Bitmap.setPixel.
A example of the body shape: https://ibb.co/KDNXhhX.
What I want to do is, that user can draw anywhere, but after the pen moved up(which means ACTION_UP), all the draw outside of the body would disapper. In other word, it only keep the draw inside the body.
I have checked the documentation about invalidate() from View, but it only invalidate a Rect or a drawable. How can I do this?

How to scale thickness or strokeWidth of line when screen size changes

I am playing around with an application that draws and traces the user's finger on the canvas. See this picture, the green rectangle was drawn by tracing the user's finger motion. I took most of the code from the old FingerPaint application from the android SDK samples. The gist of it is to draw a Path on a canvas with:
canvas.drawPath (path, paint)
My first challenge was to redraw the path correctly when the screen changes. For example, when the phone gets rotated from vertical to horizontal, the image gets resized and I have to redraw the path along the correct coordinates. I was able to correctly do that with transform. I used the path.transform(matrix) to translate the coordinates of the path.
My next challenge now is to properly scale the thickness of the line. When I draw the path, the thickness of line is set with setStrokeWidth. For example, I set the thickness to 12:
paint.setStrokeWidth(12);
I don't know how to properly scale the thickness of the line when the screen changes. Would anynone know how to do that ?
A suggestion would be to first save the canvas and the path as a bitmap and then redraw the bitmap on the new screen dimensions. But I don't want to do that because I want to support a undo/redo operations where the user can undo/redo the paths that were traced on the canvas.
you can use sth like this:
float screenWidthPixel = this.getResources().getDisplayMetrics().widthPixels;
float screenHeightPixel = this.getResources().getDisplayMetrics().heightPixels;
float STROKE_WIDTH = screenWidthPixel * 0.0035f;
float Y_POSITION = screenHeightPixel * 0.01f;
paint.setStrokeWidth(STROKE_WIDTH);

Drawing a custom shape

I need to draw a custom shape like the following.
I am trying to draw this on a Canvas for a custom view that i am trying to make. The custom view will represent a fuel level indicator.
Any ideas as to how i can achieve this drawing?
Draw what you are asking using Path, using moveTo(float x, float y) ,lineTo (float x, float y) and close() methods.
The clip the canvas to that path ( using clipPath (Path path) method of the Canvas ).
Then to make some of it red, just draw a red rectangle of appropriate height and length.

On Android how do I make oddly shaped clipping areas?

Here is how to create a clipping area the shape of a circle:
Path path = new Path();
path.addCircle(200,200,100,Direction.CW);
c.clipPath(path); // c is a Canvas
Now there's a clipping area on the Canvas which prevents drawing anything outside the bounds of that circle. But, what if I want to have the clipping area be shaped like a donut (or whatever)?
I tried playing around with creating a second Path and using toggleInverseFillType on it and then adding that to the original path, but that doesn't seem to work.
Alternatively, instead of using a Path, is it possible to just create a Bitmap to use as a mask and set it as a clipping mask on the Canvas somehow?
EDIT: The answer is exactly what I needed with one small addition. When doing multiple operations on a canvas, always use Op.REPLACE on the first clipPath call. That will replace any existing clipPath on that Canvas.
For reference, here is what I discovered what the 6 different Region.Op values mean. Imagine a venn diagram with 2 circles. "B" is the part where the 2 circles overlap. "A" is the non-overlapping left circle. "C" is the non-overlapping right circle.
c.clipPath(a,Region.Op.REPLACE);
c.clipPath(b,???);
Region.Op.DIFFERENCE -> A..
Region.Op.INTERSECT -> .B.
Region.Op.REPLACE -> .BC
Region.Op.REVERSE_DIFFERENCE -> ..C
Region.Op.UNION -> ABC
Region.Op.XOR -> A.C
The "." indicates the part that isn't drawn. Sorry if that's not particularly clear. It's hard to describe well without graphics.
From the Canvas javadoc:
Canvas#clipPath(Path path, Region.Op op) - Modify the current clip with the specified path.
So, for your donut example:
Create 2 Paths. One for the larger circle, one for the smaller circle.
Canvas#clipPath( Path ) with larger circle Path.
Call the Canvas#clipPath( Path, Region.Op ) method on your canvas with the smaller circle Path for the first argument and the appropriate Region.Op enum value for the second argument.
Path largePath = new Path();
largePath.addCircle(200,200,100,Direction.CW);
Path smallPath = new Path();
smallPath.addCircle(200,200,40,Direction.CW);
c.clipPath(largePath); // c is a Canvas
c.clipPath(smallPath, Region.Op.DIFFERENCE);
Again, modify the Region.Op enum value to get different effects...

Creating 'hole' in a RectF

I have a canvas-based drawing app that when zoomed in, I draw a miniature of the overall drawing in one corner as a scaled Bitmap. I also have a small RectF that I draw over top of the miniature, which shows you where you are in the drawing. See first attached image.
What I would like to do is to draw the scaled bitmap, then draw a RectF of the same size over top of it, with an alpha value that allows you to see the miniature, and then finally, punch a hole in the RectF that shows you where you are and allows you a clearer view of the miniature. See second attached image.
I've considered using a bitmap for the RectF with the hole already 'built-in', but as the hole will both be moving depending on location, and will change in size depending on scale factor, I need to do it dynamically.
I've looked over the RectF docs but don't see anything that would allow me to clip the RectF with a smaller RectF that would make the 'hole'. Any ideas?
You could use a Path with filling option.
moveTo 0,0 and frame the whole minipic, then moveTo the first corner inside and frame/create the hole. Not sure if it works but you can also add shapes to the path.

Categories

Resources