In Compose graphics given a `Path` and a `Rect`, w...
# compose
s
In Compose graphics given a
Path
and a
Rect
, where
Path
is a subset of
Rect
, meaning the path fits into the rectangle, how can one calculate either the amount of pixels or percentage of the path occupying the rectangle? Or in other words, how many percent does the path fill the rectangle?
A bit of background: Let's say I have a
Box
and want the user to be able to draw onto the box. I added a
pointerInput
modifier and whenever I receive a
Press
or
Move
event, I add a circle (
addOval()
) to the path at the position of the touch event. Then in a
drawWithContent
modifier I draw the path onto the box. This all works nicely and the user can draw onto the box. What I now want to achieve is to display how many percent the user has filled out the box. Any ideas?
The rectangle in this case is the area of the
Box
. I just said
Rect
for simplification 🙂
r
You can’t do this easily. The most straightforward way is to count the pixels in a bitmap. Another solution would be to flatten the path as line (there’s an api for that) and then compute the area of the resulting polygons (taking care of finding intersections and overlap though)
s
So I could draw the path to an (invisible) bitmap and count the pixels?
r
The problem can be simplified by first doing CSG on the Path using path ops
Yeah you can do that. And you can do it at a lower resolution than the screen to speed it up (also draw to alpha8 to have only one channel)
It will be an approximation but it’s good enough
I have code in Compose that does compute the signed area of a path, but it’s used as part of a larger algorithm. I should check if it can do what you want
gratitude thank you 1
s
Thanks, that would be great 🙂
r
Gimme half an hour to get to my computer
If it works I can give you something that you can just add to your project
❤️ 2
blob ty sign 1
ok got something for you
it won't be perfect because shapes are approximated by Bézier curves (so the area of a circle will be different from that of a real circle for instance) but it'll work for what you want to do
In your case you'll want to call
computeNonOverlappingArea()
s
The resulting float is a value between 0.0 and 1.0? I'm not in front of a computer anymore and will try that immediately tomorrow morning. Thanks again 🙂
r
No it gives you the area of the path itself
You'll have to divide it by the area of the surrounding rect/box yourself 🙂
s
Got it
I had to use
computeArea()
because I actually build a union of Paths like
Copy code
path += Path().apply {
  addOval(…)
}
but apart from that your solution works perfectly 🎉