I draw a line on the screen with an Android Path. -> drawPath. This path is NOT CLOSED !. So this is not a region.
I have a circle on the screen -> drawCircle.
How can I detect if the circle is touching the line ?
There are answers to similar question, but with closed path. There I could simple intersect regions. But how can we do this in case of a NOT CLOSED Path ?
Any hints ?
Try this dumb solution and optimize it if you don't find any other solution:
Create an empty bitmap
Create a canvas using that bitmap.
Draw circle in that canvas with red color.
Traverse the pixels in the bitmap and store the indices of pixel which contain red pixel.
Clear and draw that path in the canvas with black color.
Traverse all the pixels in the bitmap and if the pixel is black and check if that index exists in the indices of the circle.
If any index matches, then they overlap.
Related
As background, I am new to Android graphics. I'm trying to create a rectangle with rounded corners using Path specifically (I don't want to use method addRoundRect as I will make changes to my Path object later to not be rectangular). I want this to have the same curvature as a shape with corners with a radius of 12 dp. I'd like to use the methods rQuadTo or quadTo (based off of this question), but am a bit confused how to get the corners to match each other perfectly. Can someone explain the math behind how to to achieve this and what setting the radius exactly mean for drawable resource shape (is this a correct definition?)? Visuals would be help as well! Thanks.
Yes, link contains correct definition.
To build rounded corner with quadratic Bezier quadTo, you should start curve (end straight line) at distance r=12 before corner position, make control point exactly at corner position (to provide symmetry) and make end point at distance r after corner at perpendicular edge. Quadratic Bezier curve does not give perfect circle arc, but it is not significant for small sizes.
Example:
Horizontal edge in right direction to corner 100, 100.
End point of line is 88, 100. (and starting point of curve)
And quadto(100, 100, 100, 112)
I want a circle on the canvas in android app.
It can be done either using a bitmap of circle or actually drawing a circle.
I have done both but the circle in later has rough edges.
Why is this happening. And how can i get the Circle as i expect ?
edit:
Since android is running on phones varying in pixel density and screen size, is there a recommended method ? I want the circle to be smooth all the time.
Try
paint.setAntiAlias(true)
or set a flag during creation
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
And tell us if it works
i want to draw multiple path with multiple paint stroke width on the canvas, but overlapping problem occurs on collision of path.
color overlapping when drawing multiple path
Above link contains explanation. Overlapping occurs when i set alpha to paint. But this is requirement of application. If other way to make paint semi-transparent with using alpha.
Please suggest.
Thanks
I think it'll help you
mPaint.setARGB(90, 255, 0, 0);
mPaint.setXfermode(new AvoidXfermode(Color.RED, 90, Mode.AVOID));
if you are drawing on canvas than you need to set transparent bitmap to canvas otherwise AvoidXfermode will detect rgb of image.
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...
I have a bitmap out of which I'm cutting out a multipi point polygon. I'm curious what the correct process is for taking the pixels within the arbitrary shape and copying them onto a new bitmap where the rest of the pixels are transparent. The objective is to allow the user to trace the shape and then remove everything outside the polygon.
I have the polygon part worked out (as a an array of points), but now am stumped as to how to transfer just the selected pixels to a new Bitmap.
TIA
Not sure how your code works, but here's an idea on how to do it:
Calculate the bounding rectangle of the selected area (find min x, min y, max x and max y from your points).
Crop your image to the bounding rectangle using any of the Bitmap or Canvas-methods.
Create a Path from your points, all moved into your new bitmap (x-=minX, y-=minY);
Set your Paths FillType to one that is inverse (fill the outside).
On your new cropped canvas, draw the Path using a paint with the Xfermode as PorterDuff.CLEAR, which removes all color.