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

Sphere Fix: Add branch for empty condition in expandByPoint function #24694

Merged
merged 2 commits into from
Sep 27, 2022

Conversation

gkjohnson
Copy link
Collaborator

Related issue: --

Description

Currently when calling "Sphere.expandByPoint" on an "empty" sphere with a point that is < 1.0 distance from the sphere center nothing will happen because the radius is squared before checking if the point is already encapsulated:

sphere = new THREE.Sphere();
sphere.makeEmpty();

point = new THREE.Vector3( 0.5, 0, 0 );
sphere.expandByPoint( point );

console.log( sphere.radius ); // still - 1

cc @WestLangley

@gkjohnson gkjohnson changed the title Sphere: Add branch for empty condition in expandByPoint function Sphere Fix: Add branch for empty condition in expandByPoint function Sep 25, 2022
@gkjohnson gkjohnson added this to the r145 milestone Sep 26, 2022
@WestLangley
Copy link
Collaborator

Nice find!

I expect union() has similar problems. In fact, for both methods, I would remove the references and just calculate the new center and radius analytically.

/ping @Mugen87

@gkjohnson
Copy link
Collaborator Author

gkjohnson commented Sep 26, 2022

In fact, for both methods, I would remove the references and just calculate the new center and radius analytically.

What do you mean by this? Do you mean the comment source references? It does look like union would have the same issue. It should be simple to handle the empty cases for both spheres in that function.

@WestLangley
Copy link
Collaborator

In union(), just set the new center and radius directly, without calling expandByPoint().

Also, the "nudge" comment makes it sound like it's a hack. It's not.

@gkjohnson
Copy link
Collaborator Author

gkjohnson commented Sep 26, 2022

It looks like the nudge comment is from the original source from which this was ported 🤷:

https://github.com/juj/MathGeoLib/blob/2940b99b99cfe575dd45103ef20f4019dee15b54/src/Geometry/Sphere.cpp#L649-L671

I can plan to at least fix the union function in another PR when I get a chance unless someone beats me to it. I'll let someone else rewrite the functions if necessary.

@Mugen87
Copy link
Collaborator

Mugen87 commented Sep 26, 2022

Why is the default radius -1 and not 0? It seems expandByPoint() would work if an empty sphere has a 0 radius.

@gkjohnson
Copy link
Collaborator Author

Why is the default radius -1 and not 0? It seems expandByPoint() would work if an empty sphere has a 0 radius.

-1 is used to indicate "empty" meaning both the sphere center and radius are invalid. If "empty" was denoted by a radius of 0 then it would be impossible to tell the difference between a sphere with a center that needed to be initialized by the first point and a valid bounding sphere that encapsulated a single point at the origin.

@Mugen87
Copy link
Collaborator

Mugen87 commented Sep 26, 2022

the difference between a sphere with a center that needed to be initialized by the first point and a valid bounding sphere that encapsulated a single point at the origin.

When do you need this kind of distinction? Does it actually matter?

@gkjohnson
Copy link
Collaborator Author

The code in this PR shows the very case where this distinction is important... here is what will happen when expanding by a point ( 1, 0, 0 ) in the cases where a radius of - 1 is used and 0 is used for "empty":

Radius == 0, Center == 0, 0, 0

  • Point distance from center is measured as 1
  • Radius is set to 0.5
  • Center is moved to 0.5, 0, 0 because there's no way of knowing whether the sphere is already encapsulating the point (0, 0, 0).
  • Final sphere is radius = 0.5, center = 0.5, 0, 0

Radius == - 1, Center == 0, 0, 0

  • Sphere is seen as empty
  • Center is set to the point position since it's the only point the sphere is supposed to encapsulate
  • Radius is set to 0
  • Final sphere is radius = 0, center = 1, 0, 0

@mrdoob
Copy link
Owner

mrdoob commented Sep 27, 2022

Thanks!

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

Successfully merging this pull request may close these issues.

4 participants