Valid and invalid planes

As we stumbled upon this during debugging today…why is the first plane valid, while the second is invalid?

Both planes work for their intended purpose.

RhinoCommons quote:

Gets a value indicating whether or not this is a valid plane. A plane is considered to be valid when all fields contain reasonable information and the equation jibes with point and zaxis.

What exactly is the equation mentioned here?

Hi @rgr,

The standard equation of a plane with a non-zero normal vector is:

ax + by + cz + d = 0

– Dale

1 Like

@dale

Thank you, so that means in this case that the second plane does not pass the test and therefor qualified as not valid by rhino? What difference does it make if the plane itselft works for my case(getting transform information)? Will there be a case where I absolutly have to make sure my plane is valid?
Kinda confused as in how to handle such tests in the future, if necessary at all.

The question is, how is it possible to create an InValid Plane from a point and two Vectors?

rgr code (probably) uses “Transforms” (Plane to Plane) and the functions below to create Planes.

public static Plane PlaneFromNormal(Point3d origin, Vector3d normal)
        {
            Plane plane = new Plane(origin, normal);
            return plane;
        }

        public static Plane PlaneFromNormal(Point3d origin, Vector3d normal, Vector3d xAxis)
        {
            xAxis = new Vector3d(xAxis);
            xAxis.Unitize();

            Vector3d yAxis = Vector3d.CrossProduct(normal, xAxis);
            Plane plane = new Plane(origin, xAxis, yAxis);
            return plane;
        }

        /// <summary>
        /// Construct a plane from a point, and two vectors in the plane.
        /// </summary>
        /// <param name="origin">A 3D point identifying the origin of the plane.</param>
        /// <param name="xAxis">A non-zero 3D vector in the plane that determines the X axis direction.</param>
        /// <param name="yAxis"> A non-zero 3D vector not parallel to x_axis that is usedto determine the Y axis direction. Note, y_axis does not have to be perpendicular to x_axis.</param>
        /// <returns>The plane if successful</returns>
        public static Plane PlaneFromFrame(Point3d origin, Vector3d xAxis, Vector3d yAxis)
        {
            return new Rhino.Geometry.Plane(origin, xAxis, yAxis);
        }

Hi @rgr,

This should be functionallly equivalent to Plane.IsValid. Perhaps you find it of some use.

public static bool IsPlaneValid(Plane plane)
{
  var eq = plane.GetPlaneEquation();
  bool rc = RhinoMath.IsValidDouble(eq[0]) && // x
            RhinoMath.IsValidDouble(eq[1]) && // y
            RhinoMath.IsValidDouble(eq[2]) && // z
            RhinoMath.IsValidDouble(eq[3]);   // d, 4th coefficient of the plane equation
  if (!rc)
    return false;

  var x = eq[0] * plane.Origin.X + eq[1] * plane.Origin.Y + eq[2] * plane.Origin.Z + eq[3];
  if (Math.Abs(x) > RhinoMath.SqrtEpsilon)
  {
    double tol = Math.Abs(plane.Origin.MaximumCoordinate) + Math.Abs(eq[3]);
    if (tol > 1000.0 && plane.Origin.IsValid)
    {
      tol *= RhinoMath.SqrtEpsilon * 10.0; // far from origin
      if (Math.Abs(x) > tol)
        return false;
    }
    else
      return false;
  }

  if (!Vector3d.AreRighthanded(plane.XAxis, plane.YAxis, plane.ZAxis))
    return false;

  var n = new Vector3d(eq[0], eq[1], eq[2]);
  if (!n.IsUnitVector && !n.Unitize())
    n = Vector3d.Zero;

  x = Vector3d.Multiply(n, plane.ZAxis);
  if (Math.Abs(x - 1.0) > RhinoMath.SqrtEpsilon)
    return false;

  return true;
}
``

-- Dale

@rgr Can it be tolerance trouble? The second plane is 300.000 units away from the origin.

Hi @dale, thank you for that method, I’ll put it to use and run some tests probably next week and report back.

@arendvw: it could well be, but both planes are approx.at the same place/distance from origin in the document. It would be interesting to know if, then why.

@MartinIC ping