Search code examples
c#geometrysystem.numerics

Are System.Numerics Planes backwards?


I'm writing some geometry code using System.Numerics and I seem to have encountered a bug in the implementation of the Plane.CreateFromVertices method. The comment on Plane.D says:

The plane's distance from the origin along its normal vector.

However if I call this with three vertices at Y = 0.5 I get the plane:

N = (0, 1, 0)
D = -0.5

The D is negative! So as far as I can see either the comment is wrong, and D should be labelled:

The distance of the origin from the plane along the normal vector

or Plane.CreateFromVertices is wrong, and D should be positive.

Am I correct (in which case I shall go write a bug report), or am I misunderstanding something here (in which case, what and why?).


Solution

  • You are correct. The documentation is misleading. For example I compare two different math libraries. System.Numerics and Accord.Math

        public void RightHandRulePlane_Accord()
        {
            {
                var plane = System.Numerics.Plane.CreateFromVertices
                    (
                     new System.Numerics.Vector3( 0, 0.5f, 0 )
                     , new System.Numerics.Vector3( 1, 0.5f, 0 )
                     , new System.Numerics.Vector3( 0, 0.5f, 1 ) );
    
                Console.WriteLine( plane.ToString() );
    
                plane = System.Numerics.Plane.CreateFromVertices
                    (
                     new System.Numerics.Vector3( 0, 0.5f, 1 )
                     , new System.Numerics.Vector3( 1, 0.5f, 0 )
                     , new System.Numerics.Vector3( 0, 0.5f, 0 )
                    );
    
                Console.WriteLine( plane.ToString() );
    
            }
            {
                var plane = Accord.Math.Plane.FromPoints
                    (
                     new Accord.Math.Point3( 0, 0.5f, 0 )
                     , new Accord.Math.Point3( 1, 0.5f, 0 )
                     , new Accord.Math.Point3( 0, 0.5f, 1 ) );
    
                Console.WriteLine( plane.ToString() );
    
                plane = Accord.Math.Plane.FromPoints
                    (
                     new Accord.Math.Point3( 0, 0.5f, 1 )
                     , new Accord.Math.Point3( 1, 0.5f, 0 )
                     , new Accord.Math.Point3( 0, 0.5f, 0 )
                    );
    
                Console.WriteLine( plane.ToString() );
            }
        }
    

    the output is

    {Normal:<0, -1, 0> D:0.5}
    {Normal:<0, 1, 0> D:-0.5}
    0x -1y 0z +0.5 = 0
    0x +1y 0z -0.5 = 0
    

    The signed value +0.5 is the constant term in the equation

    ax + by + cz + d = 0
    

    You are correct in that you probably should read that as the distance from the plane origin to the coordinate system origin in the direction of the plane normal.