Calculate depth of indentation in an model using t

2020-05-09 12:20发布

问题:

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 calculate the depth of any spot in an models indentation. Current thought is to use a system in which the user selects two points outside the depth and a point within the depth of the indentation than calculate the indentations depth.

The information available to us is the three points (Vectors) in space, the distance between them and any other Vector math utilizing three points. How do we use the aforementioned data to calculate the depth of our indentation? Is it feasible and a reasonable approach to calculate a point perpendicular to the point in the depth? Thought being if this point is calculable than the depth would be the distance between those two points. How to go about this, is it feasible, is there perhaps a better approach?

回答1:

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));
    


回答2:

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.