2

I'm working on a little project in which I would like two circles to connect through a gooey effect. I've searched the web quiet a lot and came across some examples in the form of a tabbar, or sidebar menu, but that's all fixed and not what I'm looking for.

What I basically want is the following. So there is a circle and if I drag it closely to another circle it snaps together, also known as the gooey effect.

A code sample would be the best, but a direction / approach of how to do this will help me out as well.

jscs
  • 63,694
  • 13
  • 151
  • 195
  • So you want to have this effect when user is interacting with that circle and then the effect i happening when two circles meet or is going away. Right? – Saheb Roy Jan 28 '17 at 13:32
  • 1
    calculating the current shape's points for a bezier curve can be done by __[elementary geometry](https://en.wikipedia.org/wiki/Tangent_lines_to_circles)__; I recommend that reading as a good start. – holex Jan 28 '17 at 13:37
  • 1
    Maybe you can get inspired by the technique of this : https://github.com/yoavlt/LiquidFloatingActionButton – Lapinou Jan 28 '17 at 13:47
  • @holex, are you saying that you have a generalized method for deriving the control points of a Bézier curve from the curve? I can see how the link you posted would let you find the regions of both circles that would be "drawn towards" the other circle (assuming the two circles start to distort before they actually overlap.) But I've always wondered if there is a method to derive the control points for a cubic Bézier curve from the "local maximum and minimum" points on the curve. Your post implied that there is such a method. – Duncan C Jan 28 '17 at 14:37
  • And, @holex, I can see how you'd use the external tangents to find the points on each circle where you'd transition from circle arc to the curve where the "gooey" circles start to meeet, but how would you calculate bezier control points such that there are no "kinks" in the shape at the point where it transitions from each circle to the curve where the circles meet? – Duncan C Jan 28 '17 at 15:43
  • @DuncanC, the actual tangent circle's radius (they are both the same) is also calculated by your juggement, based on the distance of their centers and the difference between the both circles' radii; that is up to you how you'd establish the formula for that, different fomulas will cause different behaviours which basically can 'define' the simulated liquid's cohesion as well implicitly. – holex Jan 28 '17 at 17:08
  • @holex, the size of the "blob" that extends from each circle is, as you say, arbitrary and a matter of taste. My question is how do you select Bezier control points so that there is not a kink in the curve at the transition from the circle arc to the Bézier curve. – Duncan C Jan 28 '17 at 23:39
  • How are you creating that sample animation in Photoshop? It looks like you're using the elipse tool, but I don't know how to make the circles "gooey" like that. – Duncan C Jan 29 '17 at 13:17
  • Well you can use a couple of layers of blur and then level it back out with contrast layers. I took the gif from a medium post which explains it in a bit more detail. https://medium.com/@rehtrew/photoshop-gooey-effect-c0dda988e0d9 The only limitation of this method is, too much blur / contrast will cause the circles to get pixelated at the edges. –  Jan 29 '17 at 14:34
  • @DuncanC, the tangent points depend on the tangent circles' radii, it is one of the variables in the formula; because you need the circles 'touch' each other not intersect each other, the actual example I linked it for tangent lines (image that scenario as a circle with infinite radius), but the actual calculation is pretty much identical with tangent circles as well. – holex Jan 30 '17 at 09:18

1 Answers1

2

Interesting problem.

Off the top of my head, here is how I might handle it:

Calculate the points of intersection of the 2 circles (I found this link for that: Circle-circle intersection points)

Calculate the arc ranges of the intersecting parts of each circle.

Widen those arc ranges by a few degrees. Define the arcs for the remaining parts of each circle (The parts that would be drawn "non-gooey")

Using trig and Catmull-Rom splines, create a closed path for the outer "non-gooey" parts of each circle.

The Catmull-Rom algorithm should fill in the gaps between the 2 part-circles using smooth curves that look a lot like the "Gooey" circles you show.

I have a project on github that includes Swift code for creating Catmull-Rom splines from a series of points: Trochoid demo

That project creates open curves, not closed paths. The technique for creating smoothed closed paths using Catmull-Rom Splines is a little different. I have another Github project called RandomBlobs (Written in Objective-C) that creates smoothed closed paths. You should be able to work out how to change the Swift code to create closed paths from the Objective-C code. It's been long enough since I wrote the RandomBlobs code that I don't remember exactly what I did.

I'm not sure if the approach I describe above would be fast enough to draw in real time, but I bet it would. That TrochoidDemo project is doing a lot of trig for each animation frame, and it's animation is pretty smooth. If your project isn't smooth enough you might need to do some optimization.

Community
  • 1
  • 1
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • Sounds like an interesting mathematical approach. Going to read up on this, and see if I can work on some solution. I'm not so sure if I'm this advanced in programming yet, but like to see if I can come up with some solution. Hadn't expected that it could become this difficult, in web it's just some svg filters haha. Thanks for giving me some handle bars! I really appreciate it, and since the question is too broad, without knowing how to make it more specific I will mark yours as the correct answer. :) –  Jan 29 '17 at 12:48
  • I did notice that in your example the 2 circles begin to distort before they actually touch. Using the internal tangent lines to pick the end points for a Bézier curve, as suggested by @holex, would be a good way to get that effect, although I'm not sure how you'd get a smooth transition from the circle to the Bézier curve without kinks. – Duncan C Jan 29 '17 at 13:12
  • @DuncanC, yes, that is a good start, but the actual final solution is much simpler; what do you need for the Bezier? four center points, three radii; then you will write the linear equations of connecting the centers, then you can calculate the four tangent points on those lines by dividing the vector proportionally; if you have all those, building up the Bezier-curve is just a piece of cake, you don't even need control points for the Bezier because you are going to draw 4 regular arcs only with start- and end-angle. elementary geometry. your random guessing will drive the OP crazy. – holex Jan 30 '17 at 09:41