With circfill(), it's easily possible to draw circles everywhere, and even draw a circle with another circle cut out of it. But how would you draw the intersection of two circles, like the middle section on a venn diagram? I can't think of an easy way to do it. What I'm really looking for here is a way to shade arbitrary segments on an arbitrary venn diagram. Can anybody help?

P#74152 2020-03-23 22:06

Not exactly what you're looking for, but maybe you could look into fillp() for that? Draw one circle with fillp(0x5a5a.8) and the other with fillp(0xa5a5.8).

P#74155 2020-03-23 22:39
:: gearfo
2

When the centres of both circles lie on the same horizontal line, you can imagine a vertical line through the (I'm assuming two) points where they intersect.

The area of intersection is made up of the part the circle on the right that lies to the left of that vertical line, plus the part of the circle on the left that lies to the right of the line. So use clip() to set the clipping rectangle to be everything to the left of that line, and draw the rightmost circle, then set the clipping rectangle to the right and draw the other circle.

Cart #newegetiyu-0 | 2020-03-25 | Code ▽ | License: CC4-BY-NC-SA
2

If the centres lie on the same vertical line, it's the same idea but you're clipping above and below the horizontal line where the circles intersect.

For all other pairs of circles, the line through the points of intersection isn't horizontal or vertical, so you can't line it up with an edge of the clipping rectangle. But you can always use the equations of the circles to calculate which screen pixels are inside which circles and pset() them to the right colour. That's much less efficient, but works for any number of circles anywhere on the plane.

Cart #nupinowifa-0 | 2020-03-25 | Code ▽ | License: CC4-BY-NC-SA
2

There's probably a better way to implement that, but you get the idea -- you can test if a point lies within/on a circle using x^2 + y^2 <= r^2. Then points that are inside more than one circle can be coloured differently.

P#74190 2020-03-25 14:23

@samhocevar that's actually pretty clever :), but I can't figure out a way to have the colouring be consistent and be able to shade both the outside regions and not the middle.

@gearfo these are some fancy demos, thanks for the help! The second solution is closer to what I need, but the slowness is not great. By putting all the pixels into a table, it goes a fair bit faster, but still not close enough to the ideal 30... do you know any way of making it work faster? The circle positions can be hardcoded, but the colours need to be able to change semi-frequently.

P#74201 2020-03-25 22:47
:: gearfo
2

If the circles don't move, you could draw them onto the sprite sheet once for a fixed cost and then use sspr() and pal() to draw them on the screen with whatever colours you want each frame.

Cart #zosohemupe-0 | 2020-03-27 | Code ▽ | License: CC4-BY-NC-SA
2

You need a chunk of the sprite sheet that you're not using at the same time, obviously. You can always draw over it and reload() if you need the whole sheet for your cart, but not all at the same time as the circles.

Or you could even just draw sprites for the intersecting regions manually and add them in as patches over circles you draw with circfill(). That should work well if the whole layout is known in advance. It's not flexible, but it's fast and wouldn't use many tokens.

P#74238 2020-03-27 14:20

@gearfo Oh epic, this is exactly what I need! Thank you!

P#74257 2020-03-27 20:42