// creates an arbitrary Caresian coordinate system with given plane xy
        public static RotoTranslation3 CoordinateSystemWithPlaneXY(Plane plane)
        {
            var x = Vector3Utils.VectorOrthogonalTo(plane.Normal);
            var y = plane.Normal.Cross(x);

            return(new RotoTranslation3(Rotation3Utils.GramSchmidt(x, y), plane.ProjectOrigin()));
        }
        public void VectorOrthogonalTo_returns_Vector3_orthogonal_to_input_Vector3_which_is_not_zero_when_input_Vector3_is_not_zero
            ([ValueSource("VectorOrthogonalTo_TestCases")] Vector3 v)
        {
            var result = Vector3Utils.VectorOrthogonalTo(v);

            Expect(v * result, Is.EqualTo(0).Within(_tolerance));
            Expect(result.Norm, Is.GreaterThan(0.8 * v.Norm));
        }
        private static Vector3 Eigenvector(this SymmetricMatrix3 @this, double eigenvalue)
        {
            var rowX = new Vector3(@this.XX - eigenvalue, @this.XY, @this.ZX);
            var rowY = new Vector3(@this.XY, @this.YY - eigenvalue, @this.YZ);
            var rowZ = new Vector3(@this.ZX, @this.YZ, @this.ZZ - eigenvalue);

            var normX2 = rowX.Norm2;
            var normY2 = rowY.Norm2;
            var normZ2 = rowZ.Norm2;

            Vector3 row1, row2, row3;

            if (normX2 > normY2)
            {
                if (normX2 > normZ2)
                {
                    row1 = rowX / Math.Sqrt(normX2);
                    row2 = rowY;
                    row3 = rowZ;
                }
                else
                {
                    row1 = rowZ / Math.Sqrt(normZ2);
                    row2 = rowX;
                    row3 = rowY;
                }
            }
            else
            {
                if (normY2 > normZ2)
                {
                    row1 = rowY / Math.Sqrt(normY2);
                    row2 = rowX;
                    row3 = rowZ;
                }
                else
                {
                    row1 = rowZ / Math.Sqrt(normZ2);
                    row2 = rowY;
                    row3 = rowX;
                }
            }

            var cross2 = row1.Cross(row2);
            var cross3 = row1.Cross(row3);

            var norm22 = cross2.Norm2;
            var norm32 = cross3.Norm2;

            if (norm22 > norm32)
            {
                if (norm22 > BasicMath.Epsilon)
                {
                    return(cross2 / Math.Sqrt(norm22));
                }
                else
                {
                    return(Vector3Utils.VectorOrthogonalTo(row1).Normalized);
                }
            }
            else
            {
                if (norm32 > BasicMath.Epsilon)
                {
                    return(cross3 / Math.Sqrt(norm32));
                }
                else
                {
                    return(Vector3Utils.VectorOrthogonalTo(row1).Normalized);
                }
            }
        }