12

I'm writing a G-Code interpreter and am having difficulties determining the center of a circle when given (X, Y) for two Points on the circle and the radius. I can plot a circle from 2 Points when given the center coint, but if a radius value is given instead, I can't use that to the a center point.

I've looked up multiple examples that are written in different forms of math (calculus, geometry, trig, etc.) but can't translate any of them to code. My understanding is that the values given generate two different center/intersecting points. Those are what I need to figure out.

The interpreter is running on an Arduino and written in C. If someone could just walk me through it in pseudo code even, I would be very grateful.

Thanks!

Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
ryan lindsey
  • 145
  • 1
  • 1
  • 9
  • 5
    A circle through two points with a radius has two solutions. –  Mar 24 '16 at 22:51
  • Check [this](http://stackoverflow.com/a/4914148/1183079) answer, but instead of just sqrt, use Math.Sqrt. – Kateract Mar 24 '16 at 23:02

4 Answers4

11

Given the equation of a circle and the equations of the midpoints:

q = sqrt((x2-x1)^2 + (y2-y1)^2)

y3 = (y1+y2)/2

x3 = (x1+x2)/2

One answer will be:

x = x3 + sqrt(r^2-(q/2)^2)*(y1-y2)/q 

y = y3 + sqrt(r^2-(q/2)^2)*(x2-x1)/q  

The other will be:

x = x3 - sqrt(r^2-(q/2)^2)*(y1-y2)/q

y = y3 - sqrt(r^2-(q/2)^2)*(x2-x1)/q  

Assuming the variables for the points have been declared already, your code should look like this:

double q = Math.Sqrt(Math.Pow((x2-x1),2) + Math.Pow((y2-y1),2));

double y3 = (y1+y2)/2;

double x3 = (x1+x2)/2;

double basex = Math.Sqrt(Math.Pow(r,2)-Math.Pow((q/2),2))*(y1-y2)/q; //calculate once
double basey = Math.Sqrt(Math.Pow(r,2)-Math.Pow((q/2),2))*(x2-x1)/q; //calculate once

double centerx1 = x3 + basex; //center x of circle 1
double centery1 = y3 + basey; //center y of circle 1
double centerx2 = x3 - basex; //center x of circle 2
double centery2 = y3 - basey; //center y of circle 2

source: Link

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Chris Hawley
  • 322
  • 2
  • 15
  • i will come up with a c# version in a few hours. – Chris Hawley Mar 24 '16 at 22:53
  • Thanks for the response Chris. I must be very limited to a linear way of thinking. I have such a hard time solving for X3 and Y3 when they are on the right side of the equation. – ryan lindsey Mar 25 '16 at 02:21
  • i tried putting it all in an equation simplifier(wolfram) just to see if it could look any better. splitting up the equation might be the best thing to do as i have done. i will put c# versions of the equations in my answer – Chris Hawley Mar 25 '16 at 16:59
  • That's perfect. I can completely understand it! Thanks! – ryan lindsey Mar 26 '16 at 03:31
6

This will return one center point. You will need to alter it for the other.

In c#:

 private double CenterX(double x1,double y1, double x2, double y2,double radius)
    {
        double radsq = radius * radius;
        double q = Math.Sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));
        double x3 = (x1 + x2) / 2;


     return x3 + Math.Sqrt(radsq - ((q / 2) * (q / 2))) * ((y1 - y2) / q);


    }

    private double CenterY(double x1, double y1, double x2, double y2, double radius)
    {
    double radsq = radius * radius;
    double q = Math.Sqrt(((x2 - x1) * (x2 - x1)) + ((y2 - y1) * (y2 - y1)));

     double y3 = (y1 + y2) / 2;

      return y3 + Math.Sqrt(radsq - ((q / 2) * (q / 2))) * ((x2-x1) / q);


    }
Cody Popham
  • 992
  • 5
  • 14
4

You can't necessarily always find a unique center point give two points and a radius. In fact there are three distinct cases:

        

Case 1:

                                  

happens when the given diameter is smaller than the distance between the given points. In this case there are no solutions.

Case 2:

                                  

happens when the given diameter is exactly equal ot the distance between two points. In this case there is a trivial solution of

                                  

Case 3:

happens when the given diameter is more than the distance between the two points. In this case there are two solutions from the equations:

                                  

which you can find solutions for example from this page:

                               

where q is the distance between the two points and [x3, y3] is the middle point.

   


Here in this Gist I'm trying to implement these in C, however not finished yet. feel free to continue from where I have left.

Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Foad S. Farimani
  • 12,396
  • 15
  • 78
  • 193
0

This the ruby version of the same code, should someone need it, (thanks to C# code by rookie1024)

def chord
  @chord ||= begin
    a =  (point_1.x.to_f - point_2.x.to_f).abs ** 2
    b =  (point_1.y.to_f - point_2.y.to_f).abs ** 2
    Math.sqrt(a + b)
  end
end

def radius
  @radius ||= begin
    s = (chord / 2) * bulge
    ((chord/2) ** 2 + (s ** 2))/(2*s)
  end.to_f
end

def center
  x1 = point_1.x
  y1 = point_1.y

  x2 = point_2.x
  y2 = point_2.y

  x3 = (x1+x2)/2
  y3 = (y1+y2)/2

  basex = Math.sqrt((radius ** 2) - ((chord/2) ** 2)) * (y1-y2)/chord

  basey = Math.sqrt((radius ** 2) - ((chord/2) ** 2)) * (x2-x1)/chord

  centerx1 = x3 + basex
  centery1 = y3 + basey
  centerx2 = x3 - basex
  centery2 = y3 - basey

  bulge > 0 ? [centerx1, centery1] : [centerx2, centery2]
end
Emre Basala
  • 409
  • 4
  • 9