Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Distance Line Line wrong result #4423

Closed
ArpegorPSGH opened this issue Apr 8, 2022 · 5 comments
Closed

Distance Line Line wrong result #4423

ArpegorPSGH opened this issue Apr 8, 2022 · 5 comments
Labels
Proposal 💡 Would be nice to have

Comments

@ArpegorPSGH
Copy link
Contributor

When applying this node to parrallel lines, intersection flag is True instead of False (the distance between lines is far greater than Tolerance). Could this be corrected?

@zeffii
Copy link
Collaborator

zeffii commented Apr 9, 2022

it's behaving as intended, according to the code that implements that function.

 In case of parallel lines it will return the origin of the first line as the closest point 

sverchok/utils/geom.py

Lines 2479 to 2510 in 675f70c

def distance_line_line(line_a, line_b, result, gates, tolerance):
'''
Pass the data to the mathutils function
Deals with lines as endless objects defined by a AB segment
A and B will be the first and last vertices of the input list
In case of parallel lines it will return the origin of the first line as the closest point
'''
line_origin_a = Vector(line_a[0])
line_end_a = Vector(line_a[-1])
line_origin_b = Vector(line_b[0])
line_end_b = Vector(line_b[-1])
inter_p = intersect_line_line(line_origin_a, line_end_a, line_origin_b, line_end_b)
if inter_p:
dist = (inter_p[0] - inter_p[1]).length
intersect = dist < tolerance
is_a_in_segment = point_in_segment(inter_p[0], line_origin_a, line_end_a, tolerance)
is_b_in_segment = point_in_segment(inter_p[1], line_origin_b, line_end_b, tolerance)
local_result = [dist, intersect, list(inter_p[1]), list(inter_p[0]), is_a_in_segment, is_b_in_segment]
else:
inter_p = intersect_point_line(line_origin_a, line_origin_b, line_end_b)
dist = (inter_p[0] - line_origin_b).length
intersect = dist < tolerance
closest_in_segment = 0 <= inter_p[1] <= 1
local_result = [dist, intersect, line_a[0], list(inter_p[0]), True, closest_in_segment]
for i, res in enumerate(result):
if gates[i]:
res.append([local_result[i]])

@zeffii
Copy link
Collaborator

zeffii commented Apr 9, 2022

i think your suggestion is valid.

@zeffii zeffii added the Proposal 💡 Would be nice to have label Apr 9, 2022
@zeffii
Copy link
Collaborator

zeffii commented Apr 10, 2022

when the else is run, the dist = (inter_p[0] - line_origin_b).length part is (i think) likely (but depending on the orientation of the lines) to be an operation on the same vector3d. there inter_p[0] and line_origin_b are identical, and subtracting one from the other will result in a (0, 0, 0) and have 0 length

@ArpegorPSGH
Copy link
Contributor Author

One solution is to calculate the angle between the line's directions and if it is 0 or 180, output false for intersection.

@ArpegorPSGH
Copy link
Contributor Author

Well, after analysing it a bit, the problem just stems from a little mistake from the author of the function : instead of dist = (inter_p[0] - line_origin_b).length, it should be dist = (inter_p[0] - line_origin_a).length. Perhaps you could correct that, @zeffii.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Proposal 💡 Would be nice to have
Projects
None yet
Development

No branches or pull requests

3 participants