Friday, October 22, 2010

Flexing my Brain: Find Your Centre

I've been meaning to do a post of this type this since I started this blog, hence the "coding" part of the URL. I not sure how this popped into my head, I was just doodling on some paper some paper and somehow came up with.

"If you have three points on the circumference of a circle how do you find the centre of that circle?"

Yes, I do ponder odd things at times. To solve this graphically its pretty simple.
Given points p1,p2,and p3, construct two lines l1and l2 by connecting p1 to p2,and p2 to p3.
Find the centre point of each line m1 and m2.
From each of these points construct a line, perpendicular to the parent line and find the point intersection of these two new lines (l3and l4).
This point of intersection is the centre of the circle, from there you can calculate any and all other circular goodness you might need.

Click the image for a demonstratrion.
But then I thought, How would I implement this in code? yeah i do this often when im pondering about things.

Generally before you translate something into your programming language of choice, you must first translate it into the universal language, Mathematics.

To do this you need to know three equations;
how to get the midpoint of a line ( ( x+ x) / 2, ( y+ y) / 2 ),
how to get the equation of a line in the form  y = mx + b
and how to get the slope of a line m = ( p1y - p2y ) / ( p1x - p2x ).
These are the tools you need to get the job done.

First we find the mid points of lines l1 and l2, and call these m1 and m2
Then we get the slope of these lines, we need the line to be perpendicular so to that we need a new slope that is equal to -1/m (where m is the original slope). Now that we have a point and a new slope its simple to construct a line perpendicular to our original line in the form y = mx +b.

Now from this we have two new lines l3 and l4 and we need to find a point of intersection between these two. To do this we simply equate the two equations of y = mx + b and solve for x. Then subsitute our new value for x back into one of our line equations and solve for y. These two values for x and y are the point of intersection and by glorious hapenstance is the centre of our circle. That was a little dry so here follows a "real world" example:

Our equations are
l3: y = -x+6
l4: y = x - 4

So now we equate these and solve for x

x - 4= -x + 6
x + x = 6 +4
2x = 10
x = 5

Now with this value of x, we sub it back into our equation and we get

y = -(5) + 6
y = 1

There you have it point of intersection is x = 5, y = 1

Now to translate this into code. The midpoint, slope and perpendicular slope are pretty easy achieve.
The point of intersection while still simple took a little bit brain flexing, which now you dont have to do. 

m1x + b3 = m2x + b4
m1x - m2x = b4 - b3
x = (b4 - b3)/(m1-m2)

m1 and m2 are the perpendicular slope of line l1 and l2
b3 and b4 are the constants of the equations of l3 and l4
note: I'm aware of the slight cheating of the math but trust me it works.

//Create Three Points on Circle
Point p1 = new Point( P1X, P1Y );
Point p2 = new Point( P2X, P2Y );
Point p3 = new Point( P3X, P3Y );
//Get MidPoint of l1
Point m1 = new Point( ( ( p1.x + p2.x ) / 2 ), ( ( p1.y + p2.y ) / 2 ) );
//Get MidPoint of l2
Point m2 = new Point( ( ( p2.x + p3.x ) / 2 ), ( ( p2.y + p3.y ) / 2 ) );

//Get Slope of l1
double sl1 = ( p1.y - p2.y ) / ( p1.x - p2.x );
//Get Slope of l2
double sl2 = ( p2.y - p3.y ) / ( p2.x - p3.x );
double sl3 = -1 / sl1;
double sl4 = -1 / sl2;

double b3 = ( m1.y - ( sl3 * m1.x ) );
double b4 = ( m2.y - ( sl4 * m2.x ) );

double cx = ( b4 - b3 ) / ( sl3 - sl4 );
double cy = sl3 * cx + b3;

And there you have it in pseudo code, now granted this doesn't contain any error catching, such as what happens with a slope of 0, or making sure all three starting points are unique and not in a straight line, but the guts of it are there, and that wasn't really the point of the post.

Any questions? see me after class

No comments:

Post a Comment