1
\$\begingroup\$

https://docs.unity3d.com/ScriptReference/Plane-ctor.html

public Plane(Vector3 a, Vector3 b, Vector3 c); Description: Creates a plane.

The resulting plane goes through the given three points. The points go around clockwise as you look down on the top surface of the plane.

Since there is no Debug.DrawPlane I don't know whether my plane works as expected. Are all 3 Vectors world coordinates? Or are they connected to each other? Can somebody elaborate how this works? Neither can I make any sense of "The points go around clockwise as you look down on the top surface of the plane"

\$\endgroup\$

2 Answers 2

3
\$\begingroup\$

Any three points in space describe a plane that passes through all of those points. The points are not "connected" except in the sense that they all lie on the plane you want to describe.

The plane is in the same space that coordinates are, so if you provide world-space coordinates, the plane will be in world space.

The ordering (or winding) of the points, the part that says "the points go clockwise as you..." indicates how the front and back "sides" of the plane are determined. A plane divides 3D space into two halves, determining which side of the plane is the "front" (or top) lets us reliably talk about those two spaces.

What the clockwise bit is saying is... say you have these three points and called Plane(p0, p1, p2):

   p1

p0            p2

Note how if you trace your finger from p0 to p1 to p2, your finger moves clockwise. Further you can curl the fingers of your left hand to follow that clockwise direction. When you do that, the direction you can stick your thumb out in represents the normal of the place, and points towards the front half-space of the plane. If you do that while holding your hand up to the monitor, your thumb is probably pointing at your face. Your face is "looking down" on to the "top surface" of this plane because you see the points forming a clockwise traversal.

Note that if you called Plane(p2, p1, p0) -- the opposite order -- and your curled the fingers of your left hand to follow that now-counter-clockwise traversal, your thumb would be pointing towards the screen. Your face would then be "looking up" at the "bottom surface" of the plane.

The most common reason to care about the front side of the plane is that that is the one things usually collide with. Generally we ignore collisions with the back side of planes, although you can certainly compute them if your game needs it. Often you will need to opt-in to doing so however, as many libraries may assume you just want collisions with the front side.

\$\endgroup\$
1
  • \$\begingroup\$ Since they are labeled as Vectors I suspected the 3 Vectors added up to each other which would give a totally different plane. Thanks for clearing that up. \$\endgroup\$
    – AzulShiva
    Jan 12, 2018 at 16:42
4
\$\begingroup\$

Since there is no Debug.DrawPlane

Well, let's make our own tools to help us visualize it then.

// Mimics Debug.DrawLine, drawing a plane containing the 3 provided worldspace points,
// with the visualization centered on the centroid of the triangle they form.
public static void DrawPlane(Vector3 a, Vector3 b, Vector3 c, float size,
    Color color, float duration = 0f, bool depthTest = true) {

    var plane = new Plane(a, b, c);
    var centroid = (a + b + c)/3f;

    DrawPlaneAtPoint(plane, centroid, size, color, duration, depthTest);   
}

// Draws the portion of the plane closest to the provided point, 
// with an altitude line colour-coding whether the point is in front (cyan)
// or behind (red) the provided plane.
public static void DrawPlaneNearPoint(Plane plane, Vector3 point, float size, Color color, float duration = 0f, bool depthTest = true) {
    var closest = plane.ClosestPointOnPlane(point);
    Color side = plane.GetSide(point) ? Color.cyan : Color.red;
    Debug.DrawLine(point, closest, side, duration, depthTest);

    DrawPlaneAtPoint(plane, closest, size, color, duration, depthTest);
}

// Non-public method to do the heavy lifting of drawing the grid of a given plane segment.
static void DrawPlaneAtPoint(Plane plane, Vector3 center, float size, Color color, float duration, bool depthTest) {
    var basis = Quaternion.LookRotation(plane.normal);
    var scale = Vector3.one * size / 10f;

    var right = Vector3.Scale(basis * Vector3.right, scale);
    var up = Vector3.Scale(basis * Vector3.up, scale);

    for(int i = -5; i <= 5; i++) {
        Debug.DrawLine(center + right * i - up * 5, center + right * i + up * 5, color, duration, depthTest);
        Debug.DrawLine(center + up * i - right * 5, center + up * i + right * 5, color, duration, depthTest);
    }
}

Or, if you want to play with planes interactively, you can drop this script into an empty scene and toy with its position & inspector parameters to visualize how they affect the geometry of the plane.

public class PlaneVisualizer : MonoBehaviour {

    public Vector3 a = Vector3.right;
    public Vector3 b = Vector3.up;
    public Vector3 c = Vector3.forward;

    void OnDrawGizmos() {
        var plane = new Plane(a, b, c);

        // Draw our three input points in world space.
        // b and c are drawn as lollipops from the preceding point,
        // so that you can see the clockwise winding direction.

        Gizmos.color = Color.white;
        Gizmos.DrawWireSphere(a, 0.1f);

        Gizmos.color = Color.gray;
        Gizmos.DrawLine(a, b);
        Gizmos.DrawWireSphere(b, 0.1f);

        Gizmos.color = Color.black;
        Gizmos.DrawLine(b, c);
        Gizmos.DrawWireSphere(c, 0.1f);        

        // Draw this object's position, 
        // as a lollipop sticking out from our plane,
        // blue-green if in front (in the positive half-space),
        // and red if behind (negative half-space).           
        Gizmos.color = plane.GetSide(transform.position) ? Color.cyan : Color.red;
        Gizmos.DrawLine(plane.ClosestPointOnPlane(transform.position), transform.position);
        Gizmos.DrawWireSphere(transform.position, 0.2f);

        // Draw plane normal.
        Gizmos.color = Color.yellow;
        var center = (a + b + c) / 3f;
        Gizmos.DrawLine(center, center + plane.normal);

        // Draw planar grid.
        Gizmos.color = Color.blue;
        var matrix = Gizmos.matrix;
        Gizmos.matrix = Matrix4x4.TRS(center, Quaternion.LookRotation(plane.normal), Vector3.one);
        for(int i = -10; i <= 10; i++) {
            Gizmos.DrawLine(new Vector3(i, -10, 0), new Vector3(i, 10, 0));
            Gizmos.DrawLine(new Vector3(-10, i, 0), new Vector3(10, i, 0));
        }    
        Gizmos.matrix = matrix;
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ if I could, I'll upvote this multiple times, really helpful answer, thanks! \$\endgroup\$
    – Lotan
    Jun 1, 2021 at 11:45

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .