l i n u x - u s e r s - g r o u p - o f - d a v i s
Next Meeting:
March 3: Social gathering
Next Installfest:
Latest News:
Feb. 5: LUGOD seeking speakers for 2015
Page last updated:
2009 Mar 31 21:24

The following is an archive of a post made to our 'vox-tech mailing list' by one of its subscribers.

Report this post as spam:

(Enter your email address)
Re: [vox-tech] [OT] Math question: help me make a rainbow
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [vox-tech] [OT] Math question: help me make a rainbow

Bill Kendrick wrote:
> Tux Paint has a magic tool called "Rainbow."  It's not really, it's just
> a color-cycling circle-shaped paintbrush.  A few years ago, a couple of
> the other TP developers joked that we need a tool to draw real rainbows.
> (Draw an arc, and the rainbow gradient appears over it.)
> So I've decided it might be fun to take a stab at it.  My main problem is
> I'm rusty with math (trig., geometry, etc. ... you don't use those much in PHP
> or MySQL. ;) Heck, you don't use them much in most of the kinds of games I've
> worked on over the years.)
> Here's how I imagine the UI working.  Click mouse to select one endpoint
> of the rainbow.  Drag to where you want the other endpoint, and release
> mouse.  Rainbow gets drawn.
> The rainbow would be an upside-down-"U" shape (with a 1:1 aspect, e.g.
> it'd be a portion of a perfect circle).  I think for artistic purposes,
> it shouldn't always be a complete 180-degree arc, though.  So here's
> how I complicate the UI :)
> P1 (aka x1,y1) is where you click.  P2 (aka x2,y2) is where you release.
> 0,0 is the top left of the screen.  Angles go from 0 (bottom/right of arc)
> thru 90 (top/center of arc) to 180 (bottom/left of arc).
> If y1 >= y2, then P1 represents the 180th degree of the arc
> (going counter-clockwise from the far right of the circle), and
> P2 represents the Nth degree of the arc (where 0 <= N < 180)
> If y1 < y2, then P1 represents the Nth degree of the arc,
> and P2 represents the 0th degree.
> This will let you draw, e.g. (bad ASCII ahead):
>      /==P2
>     /
>    |
>   P1
> as well as the full semi-circular arc:
>     /==\
>    /    \
>    |    |
>   P1    P2
> and of course, if P2 is lower, then:
>     /==\
>    P1   \
>         |
>         P2
> In both cases, there's an invisible P3, which is at 0 degrees or 180 deg.,
> depending on which point ended up being lower.  The center of the circle
> is not necessarily exactly at (x1+((x2-x1)/2) , max(y1,y2)) which is where
> I'm getting stuck.
> My initial though was to find the vector V between P1 and P2.
> Going off at the normal of V, from its center, I believe I get a line
> that strikes the center of my would-be circle, when it crosses the
> max(y1,y2) height down the screen.
> But I was up late thinking about this, and worrying about atan() and
> intersect tests, and starting to think there's a simpler way.
> So, given two points on an arc of a circle, P1 and P2, how do I find
> the center and radius of the circle?  (Then all I need to do is determine
> the angle (N) of one of the points (P1 or P2), while I know that the
> angle of the other (P2 or P1) is 0 or 180, depending on my UI rules above.
> Whew.  Did I make ANY sense? :)

Some.  Not sure what you are getting at though.  You want to draw 180 degrees
of a circle with the end points defined by p1 and p2?  What if you want to
make an upside down rainbow?  Or 1/2 of one?

In any case the center is trivial.  Lets call the center M, so:
M.x = abs ( p1.x - p2.x ) / 2 + p1.x
M.y = abs ( p1.y - p2.y ) / 2 + p1.y

Oh, and radius:
r = dist ( p1 - p2 ) /2  # sqrt ( x^2 - y ^2)

Now you just need the starting angle and ending angle.

Diff_in_y = m.y - p1.y
Diff_in_x = m.y - p1.x
start_angle = tan (diff_in_y/diff_in_x)

Repeat for P2.

Then something like:

for i in start_angle to stop_angle: # this assumes degrees, but similar in
                                    # radians
   delta_x = radius * cos(i)
   delta_y = radius * sin(i)
   draw_pixel(M.x + delta_x, m.y+delta_y)

Then something like:
for color in 0 to 64:

Then inside drawHalfCircle the above with a:

vox-tech mailing list

LUGOD Group on LinkedIn
Sign up for LUGOD event announcements
Your email address:
LUGOD Group on Facebook
'Like' LUGOD on Facebook:

Hosting provided by:
Sunset Systems
Sunset Systems offers preconfigured Linux systems, remote system administration and custom software development.

LUGOD: Linux Users' Group of Davis
PO Box 2082, Davis, CA 95617
Contact Us

LUGOD is a 501(c)7 non-profit organization
based in Davis, California
and serving the Sacramento area.
"Linux" is a trademark of Linus Torvalds.

Sponsored in part by:
O'Reilly and Associates
For numerous book donations.