Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by bgulanowski · Dec 10, 2018 at 03:41 PM · raycastingcalculation

Bounds.IntersectRay() inaccurate?

I am using Ray.GetPoint() in the simplest situation, and it's returning inaccurate information.

I'm intersecting a Ray with a Bounds. The Bounds is integer-aligned. The IntersectRay() method returns an exact value. But Ray.GetPoint() returns a value with error much greater than Mathf.Epsilon.

Example:

         Bounds b = new Bounds(Vector3.one, Vector3.one * 2.0f);
         Ray r = new Ray(new Vector3(0.5f, 0.5f, -3.7f), Vector3.forward);
         float d;
 
         b.IntersectRay(r, out d);
         Vector3 p = r.GetPoint(d);



The point p should be (0.5, 0.5, 0). Instead, the Z value is off: "Ray: -3.700000E+000, Distance: 3.700000E+000, Point: -2.384186E-007"

If the Ray origin is integral, the result is as expected.

The particular ray is created by a camera which is itself at an integral point (in Z) in my test. But I want an accurate point on the surface of the bounding box, not one just outside of it.

I would like to work out the best way to adjust for the error.

One idea I have is to work out the face of the bounding box which the ray intersects. But I can't even check for the values of the point matching the min/max coordinates, because the error exceeds Epsilon.

Is there any solution besides a larger Epsilon? I can use something like 1E-006 I guess, although that's still a pretty large number, in general (although not in this case where I know I should have an integer value anyway).

UPDATE: I have done more careful analysis. The problem was not Ray.GetPoint(). It was Bounds.Raycast(). The distance value which seemed exact was actually a bit too small. I wrote a test and asserted that d == 3.7f, but instead:

  Expected: 3.70000005f
   But was:  3.69999981f
Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image TreyH · Dec 10, 2018 at 04:11 PM 0
Share

Great, so it sounds like your problem is resolved? Feel free to answer it yourself with your epsilon remark so that it can be closed.

1 Reply

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by bgulanowski · Dec 10, 2018 at 04:32 PM

Bounds.Raycast() is the culprit. I'm not sure what's going on. I worked around it by doing writing my own boundary raycast that uses Plane.Raycast().

Update: I was wrong. There is nothing strictly wrong with any of the methods. It's a seemingly unavoidable result of rounding errors.

If you define a bounding box (Bounds) at (1,1) with size (2,2), and a Ray at (-1, -1, -1) with direction (1, 1, 0), it should intersect at (0, 0, 1). But there is a rounding error.

If you do the math directly, it's (-1, -1, -1) + 2^(0.5) (2^(0.5)/2, 2^(0.5)/2, 0). Where "2^(0.5)" is the square root of two.

2^(0.5)
2^(0.5) / 2 should be 2, but it's just a little less: 0.999999... or -5.960464E-08 in the debugger.

The frustrating thing, ultimately, is as follows:

 float d;
 bounds.IntersectRay(ray, out d); // returns true
 Vector3 hit = ray.GetPoint(d); // returns slightly inaccurate value, b/c d is too small
 bounds.Contains(hit); // returns false <-- this is unfortunate.

That the point of intersection with a bounding box is not contained by the bounding box. This means I need some kid of workaround, because other calculations require that the "hit" point be on the bounding box. I think enlarging d by some amount might work.

I can't really figure out why the error is so large. Each calculation compounds the initial error, but it must be a bigger error that expected coming from either Mathf.Sqrt() or all the math functions.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Dec 12, 2018 at 04:40 AM 0
Share

Note that the epsilon is not necessary the smallest possible change since we deal with floating point values. Note that the error is extremely small. "-2.384186E-007" is just

 "-0.0000002384186"

This can safely be considered "0".


I'm not sure what you actually want to do, nut

 bounds.Contains(hit); 

doesn't make any sense. The raycast should return the hit point on the surface of the bounding box. By no means would anyone assume that this point is necessarily "inside" the bounds. There is no better solution than increasing your epsilon to a reasonable value. You get different errors depending on the size of the numbers. $$anonymous$$eep in $$anonymous$$d that the accuracy of floating point numbers "float" along with the binary point. The larger the value before the point, the less accuracy you have behind it. I've posted a table of the float format over here to get a better feeling for what values with which accuracy can be represented

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

102 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Raycast distance change object color 3 Answers

using a textured plane as a cursor, problem successfully rotating relative to RayHit.normal 1 Answer

Drawing a 3d Cone ray 2 Answers

Is it possible to make 2 raycast's collide with eachother? 1 Answer

Trouble with Projectiles, Raycasting, and 'Gravity' 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges