Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » Overlapping Circles

This thread is locked; no one can reply to it. rss feed Print
Overlapping Circles
Splizard
Member #15,703
August 2014
avatar

I am playing around with the primitives library and I am wondering if there is any way to draw circles of different colours without them overlapping each other..?

like this:
lens1.png
(Imagine the circles are different colors)
rather than this:
{"name":"40030d1336416221-how-find-distance-between-two-overlapping-circles-eclipse.jpg","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/e\/9e279ea0685bef975d4800699990efea.jpg","w":419,"h":290,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/9\/e\/9e279ea0685bef975d4800699990efea"}40030d1336416221-how-find-distance-between-two-overlapping-circles-eclipse.jpg
For example to have the circles cut at line 'C' so they don't overlap... ???

Is there a simple efficient way to go about this or should I stick to the same colour to give the illusion of not overlapping?

jmasterx
Member #11,410
October 2009

Maybe this could be done with the stencil buffer

http://en.wikipedia.org/wiki/Stencil_buffer

Or perhaps when drawing the second circle you can use clipping rect.

Yeah, clipping rect can do this.

Splizard
Member #15,703
August 2014
avatar

It would be nice if I could do it without explicitly calling OpenGL :)

Thanks, but the clipping rectangle doesn't seem to work at any angle...

al_set_clipping_rectangle(int x, int y, int width, int height)

So I guess I would then need to rotate the coordinates to achieve this at different angles?

beoran
Member #12,636
March 2011

The way to do this could be to calculate the 2 arcs using al_calculate_line, and then close the line piece by using al_calculate_line, then finally use al_draw_prim to draw the resulting figure.

https://www.allegro.cc/manual/5/al_calculate_arc

You can also use Allegro's transformations to translate and rotate coordinates.

Pho75_
Member #12,377
November 2010

i would convert the 2 circles into 2 arrays of raster lines
(same as you would for drawing triangles).
each raster has:
x1, -left side of circle
x2, -right side of circle
y, -y coord of raster line
midx -intersection coord (to be calculated)

so you can draw an entire circle by stepping through the array.

for y= y1 to y2
draw_line (x1, y, x2, y, color);

NOTE: if you have an optimized draw_hline function,
this will be faster than a generic draw_line (for software rendering).
For opengl it might not matter.

1.
sort the circles so circle1 is on the left and circle2 on the right

2.
loop thru the raster array for each circle and calculate the intersection x-coord.
To get the even split down the middle, just average the overlapping
x coordinates.

do a bounding box check on the y coordinate first.
for each raster line (y coord) from circle1 that intersects circle2
then do bounds checking to determine if they intersect for x coordinates too

if (intersects)
midx= the average of circle1_x2 and circle2_x1

3. draw each circle by looping through the raster lines.

circle1:
for y= y1 to y2
draw_line (circle1_x1, y, midx-1, y, color)

circle2:
for y= y1 to y2
draw_line (midx, y, circle2_x2, y, color)

obviously, if both circles aren't on the same y coordinate u have to do
the relative y-coord math when comparing the raster lines.

This should work for circles of different sizes too, i think.

this algorithm probably only works as long as 1 circle is not completely inside
the other circle1. You'll have to do the math to prevent that case from happening.

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Splizard said:

Thanks, but the clipping rectangle doesn't seem to work at any angle...

al_set_clipping_rectangle(int x, int y, int width, int height)

It works for me in this simple example :

#SelectExpand
1 2 3 4#include "allegro5/allegro.h" 5#include "allegro5/allegro_primitives.h" 6#include "allegro5/allegro_image.h" 7 8int main(int argc , char** argv) { 9 10 11 if (!al_init()) {return 1;} 12 if (!al_init_primitives_addon()) {return 2;} 13 if (!al_init_image_addon()) {return 3;} 14 15 al_set_new_display_flags(ALLEGRO_WINDOWED); 16 ALLEGRO_DISPLAY* display = al_create_display(300,200); 17 18 al_clear_to_color(al_map_rgb(0,0,0)); 19 20 al_set_clipping_rectangle(0,0,150,200); 21 al_draw_filled_circle(100,100,100,al_map_rgb(0,255,0)); 22 al_set_clipping_rectangle(150,0,150,200); 23 al_draw_filled_circle(200,100,100,al_map_rgb(0,0,255)); 24 25 al_save_bitmap("primclip.png" , al_get_backbuffer(display)); 26 27 al_flip_display(); 28 29 al_rest(3.0); 30 31 return 0; 32}

{"name":"608871","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/f\/1f0a8f0ef5d0ec4a6895038594a8e6af.png","w":300,"h":200,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/f\/1f0a8f0ef5d0ec4a6895038594a8e6af"}608871

Though to get rotated 'molecules' you would need to use a subbitmap to draw your circles on horizontally and then use the transformation matrix to draw it rotated on screen. The clipping gets applied after the transformation as far as I know.

Gideon Weems
Member #3,925
October 2003

The Master has a great post on this.

Splizard
Member #15,703
August 2014
avatar

@Edgar Reynaldo
It would be nice if you could set an arbitrary clipping line at any angle :-/
The need is for this to work at any angle, if you moved one of the circles around it would always merge with the other circle no matter which way they intersect.
Creating subitmaps seems maybe inefficient? If your dealing with large amounts of circles or "Molecules".

Out of the solutions above which would theoretically be the most speed efficient way?

Arthur Kalliokoski
Second in Command
February 2005
avatar

I'd think drawing actual lit 3D intersecting spheres would be easiest in the long run.

They all watch too much MSNBC... they get ideas.

Go to: