3D circle center through 3 points#1029
3D circle center through 3 points#1029SimonAndreys wants to merge 3 commits intocetz-package:masterfrom
Conversation
johannes-wolf
left a comment
There was a problem hiding this comment.
Thank you! Some small things to fix. I have not yet tested it.
src/util.typ
Outdated
| if args.len() == 4 { break } | ||
| } | ||
| // If two points are the same we take the midpoint with the two other. | ||
| if a == b or b == c { return ligne-pt(a, c, 0.5) } else if a == c { return line-pt(a, b, 0.5) } |
There was a problem hiding this comment.
Typo: ligne-pt → line-pt – maybe we should change that to vector.lerp.
src/util.typ
Outdated
| let vw = vx * wx + vy * wy + vz * wz // <v, w> | ||
| let denom = 2 * (v2 * w2 - calc.pow(vw, 2)) // 2*norm of "v cross w" | ||
| // if the points are aligned, we fail with error message returning the coordinates of the points | ||
| assert( |
There was a problem hiding this comment.
Since Typst evaluates all arguments of assert, this should be a panic inside an if.
| + str(c.at(2)) | ||
| + ") ", | ||
| ) | ||
| let lambda = w2 * (v2 - vw) / denom |
There was a problem hiding this comment.
I use typstyle to format the code, linebreaks and indentation are automatic... I put this string back to one line.
src/util.typ
Outdated
| // If two points are the same we take the midpoint with the two other. | ||
| if a == b or b == c { return ligne-pt(a, c, 0.5) } else if a == c { return line-pt(a, b, 0.5) } | ||
| // we compute the vectors b-a and c-a and the norm of their cross product | ||
| let (vx, vy, vz) = (0, 1, 2).map(i => b.at(i) - a.at(i)) // v=b-a |
There was a problem hiding this comment.
You can use range(0, 2) instead of (0, 1, 2) – same for line 114 and 145.
…ssert, range(3) instead of (0,1,2)
|
Ok, I've tested the changes. There is a problem with The current implementation does not take the point order into account, but if we want to support 3D circles, we cannot have a „default“ behavior that always works. One option would be switching to the current behavior if the normal is |
|
I understand, for any circle there are two choices of "normal direction" (defining "up" and so defining what is a counterclockwise rotation). When you flip the circle you end up with angles with opposite order (anti-trigonometric), and maybe 0deg exchanged with 180deg.
|
|
Sounds good! |
Re-wrote the function calculate-circle-center-3pt in src/utils.typ
Previously, this function took three 3D vectors as input but was essentially 2D, taking the z-coordinate from the first vector. Now the output is the center of the circle passing through the 3 point even if they have not the same z-coordinates.
Note : if two of the points are equal, there is no uniqueness of the circle center. Originally it returned the center passing through the 2 different points with x-coordinate 0, which seems arbitrary. Now it returns the midpoint between the two different points.
The function fails if the 3 points are aligned and different.
This is a first step towards making arc-through and circle-through work with 3D points with different z-coordinates.
All test passed.