Thread: Macro program to calculate circle centre

1. Macro program to calculate circle centre

Hi,

I want to find circle of centre defined by 3 points in a CNC program.
The 3 points are stored in common variables as under -

X1 = #141
Y1 = #142
X2 = #143
Y2 = #144
X3 = #145
Y3 = #146

Need help.

Thanks
Ashish

2. Originally Posted by Ashish B
Hi,

I want to find circle of centre defined by 3 points in a CNC program.
The 3 points are stored in common variables as under -

X1 = #141
Y1 = #142
X2 = #143
Y2 = #144
X3 = #145
Y3 = #146

Need help.

Thanks
Ashish
Hi Anshish, I dont think this will be easy to do with g-code see link for calcs required... How to construct (draw) a circle through 3 points with compass and straightedge or ruler - Math Open Reference

Good luck.
Keith.

3. Check this out...

http://www.cnczone.com/forums/calibr...x_y_point.html

My translation of Kiwis formula - havent had chance to test it yet...

3 point hole centre

#711= Point X 1
#721= Point Y 1

#712= Point X 2
#722= Point Y 2

#713= Point X 3
#723= Point Y 3

IF[[[#712]-[#711]]EQ[0.]]THEN[[#712]=[[#712]+0.0001]]

IF[[[#713]-[#712]]EQ[0.]]THEN[[#713]=[[#713]+0.0001]]

#715=[[#722]-[#721]]/[[#712]-[#711]]
#716=[[#723]-[#722]]/[[#713]-[#712]]

#714=[[[#715]*[#716]]*[[#721]-[#723]]+[[#716]*[[#711]+[#712]]]-[[#715]*[[#712]+[#713]]]]/[[2.]*[[#716]-[#715]]]

#724=[[-1.]/[#715]]*[[#714]-[[#711]+[#712]]/[2.]]+[[#721]+[#722]]/[2.]

#717=[SQR[[[[#712]-[#714]]*[[#712]-[#714]]]+[[[#722]-[#724]]*[[#722]-[#724]]]]]*[2.]

#714= X Circumcentre
#724= Y Circumcentre
#717= Diameter

Let us know if it works please!

DP

4. Hi Christin,

Your macro programming skill is superb. I loaded the macro program on m/c and it gave absolutely correct output without any minute correction...Hats off...
It was really a complicated coding as it involved multiple addition/subtraction equations, but you made it look so simple.
Thanks.

I kept thinking of the macro program, but i really don't understand certain coding...It goes as follows -

1. Why the following commands are commanded -
IF[[[#712]-[#711]]EQ[0.]]THEN[[#712]=[[#712]+0.0001]]
IF[[[#713]-[#712]]EQ[0.]]THEN[[#713]=[[#713]+0.0001]]

I can see that you purposely added the value of 0.0001 to the variables #712 and #713. Is there any specific reason for that?

2. I have seen many people using common variables series #101 to #149. But i am amazed to see that you have used #700 series.
Is there any specific reason for doing so

Thanks once again.
Ashish

• Ashish,

Glad to see it works, I will be using it myself eventually in my own probing routines. The credit should go to Kiwi for the formula (even with the typo - can anyone spot it? ). All I did was rewrite the formula in Excel so I could graph the results and visually confirm that it worked.

I had come up with a different approach (proven only on Excel) that was far more convoluted and would have involved about a hundred line program - understandably, I abandoned that in favour of this infallible formula.

The reason for the the 0.0001 is to ensure that the next bit does not divide by zero. There is possibly a more elegant way around that, but at the moment I can't be arsed to find it.

Every common custom macro variable I have available now serves a specific purpose, so the #700 - #799 range is the only area I can use for "temporary" storage without overwriting something important: -

#101-#160: – actual T numbers

#171 onwards: - actual P numbers

#500 Current Sequence No.

#501
. Cycle ‘Live’ Motion
. by Tool Number
. (h.mmss)
#560

#561 Sequence Start Time (dh)
#562 Sequence Start Time (ms)
#563 Last APC Time (dh)
#564 Last B-Axis Time (dh)
#565 Last T-Search Time (dh)
#566 Last ATC Time (dh)
#567 Last ATM Time (dh)
#568 ‘Live’ Motion Start (dh)
#569 Work Measure Start (ms)
#570 Total Cycle ’Live’ Time (dh)
#571 Last Sequence Completed
#572 Power-On Time (h.mmss)
#573 Warm-Up Time (h.mmss)
#575 Current Shift Date (y.md)
#576 Total APC Time (h.mmss)
#577 Total B-Axis Time (h.mmss)
#578 Total ATC Time (h.mmss)
#579 Total ATM Time (h.mmss)
#580 Total WMs Time (h.mmss)
#581 Total I/O/U Time (h.mmss)
#582 Total Powered Time (ms)
#583 Shift ‘Working’ Time %
#584 Cycle Start Time (h.mmss)
#585 Cycle End Time (h.mmss)
#586 Cycle Rework (h.mmss)
#587 Cycle Sequence (h.mmss)
#588 Cycle APC Time (h.mmss)
#589 Cycle B-Axis Time (h.mmss)
#590 Cycle ATC Time (h.mmss)
#591 Cycle ATM Time (h.mmss)
#592 Cycle WMs Time (h.mmss)
#593 Cycle I/O/U Time (h.mmss)
#594 Cycle ‘Live’ Time (h.mmss)
#595 Cycle ‘Cutting’ Time %
#596 Last Run Cycle (hh.mmss)
#597 Previous Cycle (hh.mmss)
#598 Previous Cycle (hh.mmss)
#599 Previous Cycle (hh.mmss)

#600
. Total Elapsed Time
. per Sequence -
. (N5 – N500)
#699

#700 - #799 used (rather than local macros) to perform calculations within complex sub programs or macro-driven programs/cycles.

#800
. 10° Vector Offsets
. (0°-350°)
#835

#836 Current Probe X-Runout
#837 Current Probe Y-Runout
#838 Current Angular Rotation
#839 Previous Angular Rotation
#840 Active D-word (last G123)
#841 Pallet Cline X
#842 Pallet Cline Z
#843
#844 Current Probed X-Position
#845 Current Probed Y-Position
#846 Current Probed Z-Position
#847 Current Probing Direction
#848 Previous Probed X-Position
#849 Previous Probed Y-Position
#850 Previous Probed Z-Position
#851 Previous Probing Direction
#852 Previous Probed X-Position
#853 Previous Probed Y-Position
#854 Previous Probed Z-Position
#855 Previous Probing Direction
#856 Previous Probed X-Position
#857 Previous Probed Y-Position
#858 Previous Probed Z-Position
#859 Previous Probing Direction
#860-#865 Element 01 (X/Z, Y, Target, Actual, OOT, OOP)
#866-#873 E02
#872-#877 E03
#878-#883 E04
#884-#889 E05
#890-#895 E06
#896-#901 E07
#902-#907 E08
#908-#911 E09
#912-#917 E10
#918-#923 E11
#924-#929 E12
#930-#935 E13
#936-#941 E14
#942-#947 E15
#948-#953 E16
#954-#959 E17
#960-#965 E18
#966-#971 E19
#972-#977 E20
#978-#983 E21
#984-#989 E22
#990-#997 E23
#998-#999 CUR(X/Z, Y)

DP

• Still not sure why you do not use the #1-33 as temp values for calculations. In macro calls, they are a fresh set for that macro. Granted that really does not apply here as it would only save 2 variables unless you fed the data via the macro call line ( 8 then )

For more variables, Tool offset C (4 values per tool) and more offsets then your machine has tools.

• Unless I'm working in the main pgm or a very simple sub pgm, I tend to transfer from the locals to the commons when I'm using macro calls. I then find it easier to debug my programs (I'm the type to write the whole thing then spend the rest of the day debugging it...), plus I am never sure what level I'm at variable wise when using combos of macro calls and sub calls.

Plus, I'm a control freak who likes the pgms to look scarier to deter potential rivals from learning the art

DP

• Originally Posted by Ashish B
Hi Christin,

Your macro programming skill is superb. I loaded the macro program on m/c and it gave absolutely correct output without any minute correction...Hats off...
It was really a complicated coding as it involved multiple addition/subtraction equations, but you made it look so simple.
Thanks.

I kept thinking of the macro program, but i really don't understand certain coding...It goes as follows -

1. Why the following commands are commanded -
IF[[[#712]-[#711]]EQ[0.]]THEN[[#712]=[[#712]+0.0001]]
IF[[[#713]-[#712]]EQ[0.]]THEN[[#713]=[[#713]+0.0001]]

I can see that you purposely added the value of 0.0001 to the variables #712 and #713. Is there any specific reason for that?

2. I have seen many people using common variables series #101 to #149. But i am amazed to see that you have used #700 series.
Is there any specific reason for doing so

Thanks once again.
Ashish
Following is another approach that avoids the divide by zero issue without fudging the numbers. I haven't tested the Macro language version on a machine to ensure that the syntax is correct, but I know that the math is solid.

The more eloquent method is via a simultaneous equation, and is possible to write using User Macro language, but the following example is more easily explained. I use the simultaneous equation method in CAD software and is a little more compact.

The only set of three points that will not support a circle are points on a straight line. Accordingly, a comparison of all the X and all the Y coordinates should be carried out to ensure that a straight line does not exist. If the coordinates of three points are given that all fall on a straight line, and no error trapping is done, then a divide by zero error will result where indicated in RED. You could compare all the X values and all the Y values in a Loop and if either all the X's or all the Y's are the same, generate a an error message to alert the machine operator. Alternatively, as in my approach, a test for a straight line is made where indicated in BLUE.

Regards,

Bill

The following method is derived from geometry where:

1. The mid points of the two lines formed between the three point are found. These two lines are in fact Chords of the circle you are attempting to solve.
2. Lines are then drawn perpendicular to the two lines at their respective mid points.
3. Where the two perpendicular lines intersect is the center of the circle
4. The Radius of the circle is the hypotenuse of a right triangle constructed using the circle center as one end and any one of the three points as the other end of the triangle hypotenuse.

Local variables have been used in this example.

#1= Point X1
#10= Point Y1

#2= Point X2
#20= Point Y2

#3= Point X3
#30= Point Y3

#31= Circle Center X
#32= Circle Center y

(Get the perpendicular bisector of x1, y1 and x2, y2)
#11 = [#2 + #1] / 2
#21 = [#20 + #10] / 2
#13 = #2 - #1
#23 = -[#20 - #10]

(Get the perpendicular bisector of x2, y2 and x3, y3)
#12 = [#3 + #2] / 2
#22 = [#30 + #20] / 2
#14 = #3 - #2
#24 = -[#30 - #20]

(Test for a straight line and go to error line if so)
IF [[#23 * #14 - #13 * #24]EQ[0.]] GOTO111

(See where the lines intersect)
#31 = [#21 * #23 * #24 + #12 * #23 * #14 - #11 * #13 * #24 - #22 * #23 * #24] /[#23 * #14 - #13 * #24]
#32 = [#31 - #11] * #13 / #23 + #21

#33 = SQR[[[#1 - #31]*[#1 - #31]] + [[#10 - #32]*[#10 - #32]]]

GOTO 222
(Error Message for straight line)
N111 #3006=1 (NO CIRCLE EXISTS)
N222

• Cheers Bill,

Yeah, finding out where the lines intersect was my stumbling block when I first had a crack at it, so I went down the arduous path of logical statements to ensure the end point arrived within the circle

I'd never come up with something that simple in a month of sundays!

Still, my original pgm would certainly have looked quite impressive printed off in Consolas font...

DP

ps Out of concern over the inaccuracy of fudging the figures I'll change the value to 0.000001

• Originally Posted by christinandavid
Cheers Bill,

Yeah, finding out where the lines intersect was my stumbling block when I first had a crack at it, so I went down the arduous path of logical statements to ensure the end point arrived within the circle

I'd never come up with something that simple in a month of sundays!

Still, my original pgm would certainly have looked quite impressive printed off in Consolas font...

DP

ps Out of concern over the inaccuracy of fudging the figures I'll change the value to 0.000001
Hi, is it Christin or David? (DP)

I'm not wanting to seem like nit picking, just like to know the logic behind the fudge. Is it only to avoid the divide by Zero error that would otherwise result?

I think what you have tried to a achieve with your following code is a type of straight line test, but only in the X axis; no test for the Y axis. Also, rather than indicate that the line is straight, a circle of extraordinarily large diameter is being forced from what would otherwise may have been a straight line. This could result in its own set of problems when the machine tried to follow that arc if requested to do so. Using 0.000001 in the calc will only exacerbate this latter issue.

However, as [[#712]-[#711]] and [[#713]-[#712]] are used separately further down, it seems that no two X coordinates are allowed to be the same, so not really a straight line test in its true sense.

I see also that by the time the comparison is made between #713 and #712, #712 has been seeded. Accordingly, the three points may not have been on a straight line initially.

Regards,

Bill

IF[[[#712]-[#711]]EQ[0.]]THEN[[#712]=[[#712]+0.0001]]

IF[[[#713]-[#712]]EQ[0.]]THEN[[#713]=[[#713]+0.0001]]

#715=[[#722]-[#721]]/[[#712]-[#711]]
#716=[[#723]-[#722]]/[[#713]-[#712]]

• I'm pretty sure that I put it in there because when I converted the original formula (in Excel) into something I could translate to macro b, the divide by zero issue arose - its not a test for a straight line - its just to remove the possibility of a zero difference between the original points that would indeed be an issue on the next part of the program. ie: -

#715=[[#722]-[#721]]/[[#712]-[#711]] <----won't like it if #712-#711 is zero
#716=[[#723]-[#722]]/[[#713]-[#712]] <-----ditto

Remember, I have painstakingly taken something that made mathematical sense in it's original form and used brute force to make it look like something that will run on the machine. I never actually sat down and tried to understand it

David P

• ps the odds of me probing three points that lie in a straight line, even if its supposed to be a straight line, are pretty remote....

• Page 1 of 4 1234 Last