FullControlXYZ / fullcontrol

Python version of FullControl for toolpath design (and more) - the readme below is best source of information

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

angleXY_between_3_points returns outside angle

FrostiFish opened this issue · comments

Hi there!
I created an implementation for an arc which goes through three points, it is functioning in my fork of fullcontrol, it's called three_point_arcXY. It has several added functions to achieve this. It uses arcXY to draw the final arc, with the arc_angle being obtained from the angleXY_between_3_points. In three out of four cases, the arc_angle is displayed correctly, however, one out of four cases has the outside angle around three points displayed.

Case 1:
WhatsApp Image 2023-09-17 at 18 55 02_26ffdcca

Case 2:
WhatsApp Image 2023-09-17 at 18 57 29_cbe39527

Case
WhatsApp Image 2023-09-17 at 18 57 43_7adf8af1
3:

Case 4:
WhatsApp Image 2023-09-17 at 18 56 48_89083743

I could not resolve this, so I added an invert option to three_point_arcXY in the meantime.
My guess is that this is because of something in angleXY_between_3_points going wrong.

Hope you can help me out :)

Best regards,
Hannah

Hi, this sometimes happens when angles are limited to 0-360, or -180 to +180 or 0-pi, etc. since your arc points may be 350, 360, 370 degrees, but that data may be naturally converted to 350, 0, 10 but maths functions.

I've just pushed a few minor changes, which are relevant by the way. One of them is circleXY_3pt(). I can see you already have the things you need, but my code might be of interest somehow.

For your problem, I would do something like this:

  • polar1 = polar angle of point 1
  • polar2 = polar angle of point 2
  • polar3 = polar angle of point 3

if polar2 > polar1 and polar3 < polar 2: polar2 += tau
if polar2 < polar1 and polar3 > polar 2: polar2 -= tau

That code concept will likely need some tweaking, but the idea is to make sure that the polar angles of the three points either continuously increase or continuously decrease.

Make sense?

There are no doubt nice mathsy ways to do this in a single line, but this way makes sense and is understandable

Andy

Hi Andy, your explanation is nice and clear. I checked out the newly added circle_3pt(), and it looks nice and efficient.
Would my changes still be useful for the full control project? I think the helper functions might be useful, but the arc adaptation might be better suited to a one-liner to save on function calls.

Your function for an arc from 3 points would definitely be useful. Did you manage to solve the issue of it not going through point 2 sometimes? Which other functions did you think are most useful?

I did not update the three-point arc, I can get to this later and re-implement it using the math from circleXY_3pt().

Regarding my other functions, you might want to take a look at intersectXY() in the file intersect.py. They will calculate an intersecting point in the X and Y axis, as long as it describes two lines which aren't parallel, which can be done from both two sets of points or two sets of a point and a vector.
It would be nice to create a 3D version at some point, but this 2D version is less intense to calculate.
centreXY_from_3_points in the file measure.py might be a nice addition as well.
Lastly, the functions in perpendicular_vector.py might also be useful to some.

Let me know what you think, then I can send a pull request :)

Thanks for this update. I believe many of these functions are already in the existing code, but just not very well separated out.

E.g. the current circleXY_3pt function calculates the centre point with this code:

    D = 2 * (pt1.x * (pt2.y - pt3.y) + pt2.x * (pt3.y - pt1.y) + pt3.x * (pt1.y - pt2.y))
    if D == 0:
        raise Exception('The points are collinear, no unique circle')
    x_centre = ((pt1.x**2 + pt1.y**2) * (pt2.y - pt3.y) + (pt2.x**2 + pt2.y**2) * (pt3.y - pt1.y) + (pt3.x**2 + pt3.y**2) * (pt1.y - pt2.y)) / D
    y_centre = ((pt1.x**2 + pt1.y**2) * (pt3.x - pt2.x) + (pt2.x**2 + pt2.y**2) * (pt1.x - pt3.x) + (pt3.x**2 + pt3.y**2) * (pt2.x - pt1.x)) / D

I've just checked and although I do like you're code for the human-readable-ness and re-use of other functions, this above code is about 6x quicker to run. So I'm going to pull that code out of the circleXY_3pt function and move it to measure.py as a centreXY_3pt or a similar name. Does that sounds good or am I missing something out?

I like the simple perpendicular vector stuff. Can you add a brief description to say it follows the right-hand rule with a vector from pt1 to pt2? Or consider replacing with start_point and end_point if you think that makes more sense.

For the interception stuff, I think your functions already exist in lab.fullcontrol.geometry.intercept don't they? They will move to the main package at some point. I just want to test them a bit more first.

If you're not able to do coding right now, but agree with the above, submit a pull request with only the perpendicular vector stuff and I'll make any tweaks and pull out the circleXY_3pt function during or immediately-after merging

Cheers,

Andy

Thanks for your reply. Your implementation looks very clean, nice and efficient :)
Your plan sounds good, should I submit a pull request? I will add the description to perpendicular vector. I saw you already added mid_point :)
My fork has some changes to the Voron Zero printer config. I see you added changes to the voron_zero.py printer config. I faced problems after updating my Klipper version. The PRINT_END macro at the end of the file got ignored and did not trigger cooldown etc.
In my fork of full control, I added a blank newline after PRINT_END, which fixed this issue. I also changed the styling of PRINT_START and PRINT_END from lower case, to caps, which is how it's usually written Klipper.

If this is all OK, then I will close this issue

Kind regards,
Hannah

Sounds good!

Great!