Guidance for circle intersections

Hello,

I am looking for some guidance on the best way to go about a project I am working on.

Here is the goal: create a cylinder that has multiple holes that can be re-sized and moved without intersecting with each other (plus a “buffer” septum distance to keep a constant minimum distance between the holes) or the outer bounds of the cylinder itself.

Ideally, I would like to be able to make this work for 2 holes, 3 holes, 4 holes, and so on.

One challenge is that using the bounding box will not give an accurate intersection as the corners of the box are further from the center of the circle as illustrated.

I have created a semi-working demo that shows what I am trying to achieve though it feels messy and overly complicated. Any advice on the best way to go about this?

Demo Link

Thanks for your input!

Seems, you don’t need bounding boxes, you need radii.
If the distance between two circles is less than sum of their radii, then collision happened. :thinking:

1 Like

I once faced a similar problem with my Catenary Playground, just the other way around: I didn’t allow for two draggable points to be farther apart from each other than a fixed length. While you don’t want them to come closer than an allowed distance in your application. Like @prisoner849 correctly stated, these are radial constraints.

Please study in the attached Codepen the event handlers for the TransformControl’s “change” event (lines 121-172) and “dragging-changed” event (lines 174-188).

The “change” event gets fired while you are dragging. In its handler, I’m applying checks for the allowed distance between the two points and clamp as necessary.

The “dragging-changed” event gets fired once you release the mouse button. Only then I apply the dragged (and possibly clamped) new position.

https://codepen.io/Chrisssie/pen/dPyadrz

3 Likes

Made this funny sketch with 2d-context and a little bit of three.js

Collision of circles:

Demo: https://codepen.io/prisoner849/full/ogXvwae

:double_exclamation_mark: WARNING! Contains sound! :double_exclamation_mark:

5 Likes

Ah, reminds me of this (the black object tries to avoid collision):

https://x.com/PavelBoytchev/status/1767500903244759251

3 Likes

That’s a cool visualisation, as always, but not so much related to the TO’s quest, IMO:

The TO would like to maintain a “septum” distance on convex approaches with different “holes”, and a convex-concave septum between the outer cylinder and any of the holes.

1 Like

This is one of those problems that isn’t that difficult to solve, but in practice is enough code that solving it for a demo feels like actual unpaid work. :smiley:

And as soon as its “solved” there will be new requirements/modifications…

4 Likes

Why not?
Computing the sum of radii, take into account some value that represents “septum”.
And the same approach for the outer circle: subtract the “septum” amount from its radius.
Or the problem is way complex, but I see it as something simple :sweat_smile:

3 Likes

Paul, please don’t feel offended. I like (and admire) your work very much.

But technically, and probably also from the point of view of the TO, avoiding collision and maintaining a septum on both convex (other holes) and concave (outer diameter of cylinder) contacts are very different things. Even though they are (mathematically speaking) algorithmically similar.

I believe you can’t expect every poster to grasp this similarity.

No offence at all :slight_smile:

I provided my sketch mostly as a proof-of-concept for “use radii instead of bounding boxes”. Didn’t think that it’s not that obvious with adding of the “septum” in calculations, so yes, I agree with you on that. :handshake:

2 Likes
Offtopic

I’m not quite sure why with and without septum makes the story very different. Maybe this is just a matter of personal perspective, when something is obvious to one person, and not obvious to another person.

If anyone wants something to ponder on, modify @prisoner849’s code in line 91 from:

if(dist < (sumRadii)){

to

if(dist < (sumRadii+1)){

Only +1 is added, but this creates magnetic attraction. A nice mental exercise is to explain why does this happen.

2 Likes

if(dist < (sumRadii * 1.5 )) start several times. Always results in different arrangements.

A beautiful toy.
:smiley:

3 Likes

Sounds like moving only half the distance needed each time and calling constrain iteratively might do the trick.

1 Like