Calculate depth of indentation in an model using three point system?

后端 未结 2 1653
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-29 05:16

Via Raycasting one can select a point on an GameObjects Collider. In the short visual three points are represented with small spheres denoting user selection. The desire is to c

相关标签:
2条回答
  • 2021-01-29 05:43

    To complement Ruzihm's answer, as I pointed in the previous question you really need 4 (3+1) points. 3 (2+1) points are still not enough. Going back to my previous example assume that one point on the surface plane a is A is (0,0,0), another B is (0,0,1), and the point on the indentation plane b is I is (2,1,0). How deep is the indentation? The answer is: you still don't know. Adding the point B still left valid two choices from that example:

    • a is X = 0 while b is X = 2. Then the indentation depth is clearly 2.
    • a is Y = 0 while b is Y = 1. Then the indentation depth is clearly 1.

    And there are still infinitely many other options.

    This happens because two points (A and B) only fix a line rather than whole plane. To fix a plane you really need 3 points (not lying on the same line). And this is what Ruzihm's answers does.

    0 讨论(0)
  • 2021-01-29 05:44

    This is a pretty open question because simply "depth" is pretty vague. Here are two approaches if you can find some points on the model in world space:

    Method 1: Create reference plane from 3 points on surface.

    1. Have the user click on the point whose "depth" they want to know.

      RaycastHit indentHit;
      Vector3 depthPoint = indentHit.point;
      
    2. Have the user click on three points outside of the "indentation". These three points define a plane that we are going to use as a reference for our "depth" measurement.

      RaycastHit hitA;
      RaycastHit hitB;
      RaycastHit hitC;
      
      Vector3 a = hitA.point;
      Vector3 b = hitB.point;
      Vector3 c = hitC.point; 
      
      Plane surfacePlane = new Plane(a, b, c); 
      
    3. Find the distance of the point from the plane using Plane.GetDistanceToPoint. We don't care about the direction, just the distance, so we use Mathf.Abs to make sure our distance is positive:

      float depth = Mathf.Abs(surfacePlane.GetDistanceToPoint(depthPoint));
      

    Method 2: Create reference plane from 1 point on surface and its normal.

    Another way you can do it is by taking one point on the surface of the model and one point on the indentation, and creating a plane out of the single point on the surface of the model and using its normal to create a plane from that one point:

    1. Have the user click on the point whose "depth" they want to know.

      RaycastHit indentHit;
      Vector3 depthPoint = indentHit.point;
      
    2. Have the user click on one point outside of the "indentation". Then, find the normal at that point. From these, you can generate a plane.

      RaycastHit surfaceHit;
      Vector3 surfacePoint = surfaceHit.point;
      Vector3 surfaceNormal = surfaceHit.normal;
      
      Plane surfacePlane = new Plane(surfaceNormal.normalized, surfacePoint);
      

      Something that might be worth trying is allowing for taking multiple points and normals and averaging them out to create the plane. If you try this, just make sure that you get the normalized form of the normal.

    3. Find the distance of the point from the plane using Plane.GetDistanceToPoint. We don't care about the direction, just the distance, so we use Mathf.Abs to make sure our distance is positive:

      float depth = Mathf.Abs(surfacePlane.GetDistanceToPoint(depthPoint));
      
    0 讨论(0)
提交回复
热议问题