Beispiel #1
0
        /// <summary>
        /// This function returns the vector (or cross) product of two input directions.
        /// The input directions must be three-dimensional.
        /// The result is always a vector which is unitless.
        /// If the input directions are either parallel or anti-parallel a vector of zero magnitude is returned.
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns></returns>
        public static IfcVector IfcCrossProduct(IfcDirection arg1, IfcDirection arg2)
        {
            if (arg1 == null || arg1.Dim != 3 || arg2 == null || arg2.Dim != 3)
            {
                return(null);
            }

            doublewrapper         Mag;
            IfcDirection          Res;
            IList <doublewrapper> V1, V2;

            V1  = new List <doublewrapper>(IfcNormalise(arg1).DirectionRatios.Items);
            V2  = new List <doublewrapper>(IfcNormalise(arg2).DirectionRatios.Items);
            Res = new IfcDirection(V1[1] * V2[2] - V1[2] * V2[1], V1[2] * V2[0] - V1[0] * V2[2], V1[0] * V2[1] - V1[1] * V2[0]);
            Mag = 0;
            for (int i = 0; i < 3; i++)
            {
                Mag += Res.DirectionRatios[i] * Res.DirectionRatios[i];
            }
            if (Mag > 0)
            {
                return(new IfcVector(Res, Math.Sqrt((double)Mag)));
            }
            else
            {
                return(new IfcVector(arg1, 0));
            }
        }
Beispiel #2
0
        private static IfcVector IfcVectorDifference(double Mag1, IfcDirection Vec1, double Mag2, IfcDirection Vec2)
        {
            IfcDirection  Res;
            doublewrapper Mag;
            int           nDim;

            Vec1 = IfcNormalise(Vec1);
            Vec2 = IfcNormalise(Vec2);
            nDim = Vec1.DirectionRatios.Items.Length;
            Mag  = 0;
            Res  = new IfcDirection();
            doublewrapper[] temp = new doublewrapper[nDim];
            for (int i = 0; i < nDim; i++)
            {
                temp[i] = 0;
            }
            Res.DirectionRatios = (IfcDirectionDirectionRatios)temp;

            for (int i = 0; i < nDim; i++)
            {
                Res.DirectionRatios[i] = Mag1 * Vec1.DirectionRatios[i] - Mag2 * Vec2.DirectionRatios[i];
                Mag += Res.DirectionRatios[i] * Res.DirectionRatios[i];
            }

            if (Mag > 0)
            {
                return(new IfcVector(Res, Math.Sqrt((double)Mag)));
            }
            else
            {
                return(new IfcVector(Vec1, 0));
            }
        }
Beispiel #3
0
        /// <summary>
        /// This function returns a direction whose components are normalized to have a sum of squares of 1.0.
        /// If the input argument is not defined or of zero length then null is returned.
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static IfcDirection IfcNormalise(IfcDirection arg)
        {
            if (arg == null)
            {
                throw new ArgumentNullException("arg");
            }
            IfcDimensionCount1 Ndim;
            IfcDirection       V = new IfcDirection(1, 0);
            doublewrapper      Mag;

            Ndim = arg.Dim;
            V.DirectionRatios = arg.DirectionRatios;

            Mag = 0;
            for (int i = 0; i < Ndim; i++)
            {
                Mag += V.DirectionRatios[i] * V.DirectionRatios[i];
            }

            if (Mag <= 0)
            {
                return(null);
            }

            Mag = Math.Sqrt((double)Mag);
            for (int i = 0; i < Ndim; i++)
            {
                V.DirectionRatios[i] /= Mag;
            }

            return(V);
        }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Dim"></param>
        /// <param name="axis1"></param>
        /// <param name="axis2"></param>
        /// <param name="axis3"></param>
        /// <returns></returns>
        public static IList <IfcDirection> IfcBaseAxis(int Dim, IfcDirection axis1, IfcDirection axis2, IfcDirection axis3)
        {
            if (Dim != 3)
            {
                return(null);
            }
            if (axis1 == null)
            {
                return(null);
            }
            if (axis2 == null)
            {
                return(null);
            }
            if (axis3 == null)
            {
                return(null);
            }

            IList <IfcDirection> U = new List <IfcDirection>(Dim);
            IfcDirection         D1, D2;

            D1 = Functions.NVL <IfcDirection>(IfcNormalise(axis3), new IfcDirection(0, 0, 1));
            D2 = IfcFirstProjAxis(D1, axis1);
            U.Add(D2);
            U.Add(IfcSecondProjAxis(D1, D2, axis2));
            U.Add(D1);

            return(U);
        }
Beispiel #5
0
 /// <summary>
 /// This function returns the difference of the input arguments as (Arg1 - Arg2).
 /// The function returns as a vector the vector difference of the two input vectors.
 /// The input arguments shall both be of the same dimensionality but may be either directions or vectors.
 /// If both input arguments are vectors they must be expressed in the same units, if both are directions a unitless result is produced.
 /// A zero difference vector produces a vector of zero magnitude.
 /// </summary>
 /// <param name="arg1"></param>
 /// <param name="arg2"></param>
 /// <returns></returns>
 public static IfcVector IfcVectorDifference(IfcDirection arg1, IfcVector arg2)
 {
     if (arg1 == null || arg2 == null || arg1.Dim != arg2.Dim)
     {
         return(null);
     }
     return(IfcVectorDifference(1, arg1, arg2.Magnitude, arg2.Orientation.Item));
 }
Beispiel #6
0
 /// <summary>
 /// This function returns a direction which is the orthogonal complement of the input direction.
 /// The input direction must be a two-dimensional direction and the result is a vector of the same type and perpendicular to the input vector.
 /// </summary>
 /// <param name="Vec"></param>
 /// <returns>Null if the parameter Vec is null, or if Vec is not of 2 dimensions.</returns>
 public static IfcDirection IfcOrthogonalComplement(IfcDirection Vec)
 {
     if (Vec == null || Vec.Dim != 2)
     {
         return(null);
     }
     return(new IfcDirection(-(double)Vec.DirectionRatios[1], (double)Vec.DirectionRatios[0]));
 }
Beispiel #7
0
        /// <summary>
        /// This function returns the difference of the input arguments as (Arg1 - Arg2).
        /// The function returns as a vector the vector difference of the two input vectors.
        /// The input arguments shall both be of the same dimensionality but may be either directions or vectors.
        /// If both input arguments are vectors they must be expressed in the same units, if both are directions a unitless result is produced.
        /// A zero difference vector produces a vector of zero magnitude.
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns></returns>
        public static IfcVector IfcVectorDifference(IfcDirection arg1, IfcDirection arg2)
        {
            if (arg1 == null || arg2 == null || arg1.Dim != arg2.Dim)
            {
                return(null);
            }

            return(IfcVectorDifference(1, arg1, 1, arg2));
        }
Beispiel #8
0
        /// <summary>
        /// This function returns two orthogonal directions. u[1] is in the direction of ref_direction and u[2] is perpendicular to u[1].
        /// A default value of (1.0,0.0,0.0) is supplied for ref_direction if the input data is incomplete.
        /// </summary>
        /// <param name="refDirection"></param>
        /// <returns></returns>
        public static IList <IfcDirection> IfcBuild2Axes(IfcDirection refDirection)
        {
            IfcDirection         D    = NVL <IfcDirection>(IfcNormalise(refDirection), new IfcDirection(1, 0));
            IList <IfcDirection> axes = new List <IfcDirection>(2);

            axes.Add(D);
            axes.Add(IfcOrthogonalComplement(D));
            return(axes);
        }
Beispiel #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="Dim"></param>
        /// <param name="axis1"></param>
        /// <param name="axis2"></param>
        /// <returns></returns>
        public static IList <IfcDirection> IfcBaseAxis(int Dim, IfcDirection axis1, IfcDirection axis2)
        {
            if (Dim != 1 || Dim != 2)
            {
                return(null);
            }

            IList <IfcDirection> U = new List <IfcDirection>(Dim);
            double       Factor;
            IfcDirection D1;

            if (axis1 != null)
            {
                D1 = IfcNormalise(axis1);
                U.Add(D1);
                U.Add(IfcOrthogonalComplement(D1));
                if (axis2 != null)
                {
                    Factor = IfcDotProduct(axis2, U[1]);
                    if (Factor < 0)
                    {
                        U[1].DirectionRatios[0] = -U[1].DirectionRatios[0];
                        U[1].DirectionRatios[1] = -U[1].DirectionRatios[1];
                    }
                }
            }
            else
            {
                if (axis2 != null)
                {
                    D1 = IfcNormalise(axis2);
                    U.Add(IfcOrthogonalComplement(D1));
                    U.Add(D1);
                    U[0].DirectionRatios[0] = -U[0].DirectionRatios[0];
                    U[0].DirectionRatios[1] = -U[0].DirectionRatios[1];
                }
                else
                {
                    U.Add(new IfcDirection(1, 0));
                    U.Add(new IfcDirection(0, 1));
                }
            }
            return(U);
        }
Beispiel #10
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="arg1"></param>
        /// <param name="arg2"></param>
        /// <returns></returns>
        public static double IfcDotProduct(IfcDirection arg1, IfcDirection arg2)
        {
            if (arg1 == null)
            {
                return(0);
            }
            if (arg2 == null)
            {
                return(0);
            }
            int    dim = arg1.Dim < arg2.Dim ? (int)arg1.Dim : (int)arg2.Dim;
            double tmp = 0;

            for (int i = 0; i < dim; i++)
            {
                tmp += (double)arg1.DirectionRatios[i] * (double)arg2.DirectionRatios[i];
            }
            return(tmp);
        }
Beispiel #11
0
        /// <summary>
        /// This function produces a three dimensional direction which is, with fully defined input,
        /// the projection of arg onto the plane normal to the z-axis.
        /// With arg defaulted the result is the projection of (1.0,0.0,0.0) onto this plane
        /// except that if z-axis = (1.0,0.0,0.0) then (0.0,1.0,0.0) is used as initial value of arg
        /// A violation occurs if arg is in the same direction as the input z-axis.
        /// </summary>
        /// <param name="zAxis"></param>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static IfcDirection IfcFirstProjAxis(IfcDirection zAxis, IfcDirection arg)
        {
            if (zAxis == null)
            {
                return(null);
            }

            IfcDirection xAxis, V, Z;
            IfcVector    xVec;

            Z = IfcNormalise(zAxis);
            if (arg == null)
            {
                if (Z.DirectionRatios[0] != 1 || Z.DirectionRatios[1] != 0 || Z.DirectionRatios[2] != 0)
                {
                    V = new IfcDirection(1, 0, 0);
                }
                else
                {
                    V = new IfcDirection(0, 1, 0);
                }
            }
            else
            {
                if (arg.Dim != 3)
                {
                    return(null);
                }
                if (IfcCrossProduct(arg, Z).Magnitude == 0)
                {
                    return(null);
                }
                else
                {
                    V = IfcNormalise(arg);
                }
            }

            xVec  = IfcScalarTimesVector(IfcDotProduct(V, Z), Z);
            xAxis = IfcVectorDifference(V, xVec).Orientation.Item;
            return(IfcNormalise(xAxis));
        }
Beispiel #12
0
        /// <summary>
        /// This function returns a vector whose components are normalized to have a sum of squares of 1.0.
        /// If the input argument is not defined or of zero length then null is returned.
        /// </summary>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static IfcVector IfcNormalise(IfcVector arg)
        {
            if (arg == null)
            {
                throw new ArgumentNullException("arg");
            }
            IfcDimensionCount1 Ndim;
            IfcDirection       V   = new IfcDirection(1, 0);
            IfcVector          Vec = new IfcVector(new IfcDirection(1, 0), 1);
            doublewrapper      Mag;

            Ndim = arg.Dim;
            V.DirectionRatios = arg.Orientation.Item.DirectionRatios;
            Vec.Magnitude     = arg.Magnitude;
            Vec.Orientation   = (IfcVectorOrientation)V;
            if (arg.Magnitude == 0)
            {
                return(null);
            }
            Vec.Magnitude = 1;

            Mag = 0;
            for (int i = 0; i < Ndim; i++)
            {
                Mag += V.DirectionRatios[i] * V.DirectionRatios[i];
            }

            if (Mag <= 0)
            {
                return(null);
            }

            Mag = Math.Sqrt((double)Mag);
            for (int i = 0; i < Ndim; i++)
            {
                V.DirectionRatios[i] /= Mag;
            }

            Vec.Orientation = (IfcVectorOrientation)V;
            return(Vec);
        }
Beispiel #13
0
        /// <summary>
        /// This function returns the normalized vector
        /// that is simultaneously the projection of arg onto the plane normal to the vector z-axis
        /// and onto the plane normal to the vector x-axis.
        /// If arg is NULL then the projection of the vector (0.,1.,0.) onto z-axis is returned.
        /// </summary>
        /// <param name="zAxis"></param>
        /// <param name="xAxis"></param>
        /// <param name="arg"></param>
        /// <returns></returns>
        public static IfcDirection IfcSecondProjAxis(IfcDirection zAxis, IfcDirection xAxis, IfcDirection arg)
        {
            IfcVector    yAxis, temp;
            IfcDirection V;

            if (arg == null)
            {
                V = new IfcDirection(0, 1, 0);
            }
            else
            {
                V = arg;
            }

            temp  = IfcScalarTimesVector(IfcDotProduct(V, zAxis), zAxis);
            yAxis = IfcVectorDifference(V, temp);
            temp  = IfcScalarTimesVector(IfcDotProduct(V, xAxis), xAxis);
            yAxis = IfcVectorDifference(yAxis, temp);
            yAxis = IfcNormalise(yAxis);
            return(yAxis.Orientation.Item);
        }
Beispiel #14
0
        /// <summary>
        /// This function returns the vector that is the scalar multiple of the input vector.
        /// It accepts as input a scalar and a 'vector' which may be either a Direction or a Vector.
        /// The output is a Vector of the same units as the input vector or unitless if a direction is input.
        /// If either input argument is undefined then the returned vector is also undefined.
        /// </summary>
        /// <param name="scalar"></param>
        /// <param name="vec"></param>
        /// <returns></returns>
        public static IfcVector IfcScalarTimesVector(double scalar, IfcDirection vec)
        {
            if (vec == null)
            {
                return(null);
            }

            IfcDirection V;
            double       Mag;

            V   = vec;//FIXME clone?
            Mag = scalar;

            if (Mag < 0)
            {
                for (int i = 0; i < V.DirectionRatios.Items.Length; i++)
                {
                    V.DirectionRatios[i] = -V.DirectionRatios[i];
                }
                Mag = -Mag;
            }
            return(new IfcVector(IfcNormalise(V), Mag));
        }
 /// <summary>
 /// Constructor from an IfcDirection
 /// </summary>
 /// <param name="dir"></param>
 public IfcAxis2Placement2DRefDirection(IfcDirection dir)
 {
     this.Item = dir;
 }
 /// <summary>
 /// Constructor allowing the underlying item to be given
 /// </summary>
 /// <param name="dir"></param>
 public IfcVectorOrientation(IfcDirection dir)
 {
     this.Item = dir;
 }
 /// <summary>
 /// Constructor allowing the underlying data to be given
 /// </summary>
 /// <param name="orient"></param>
 /// <param name="mag"></param>
 public IfcVector(IfcDirection orient, double mag)
 {
     this.Orientation = (IfcVectorOrientation)orient;
     this.Magnitude   = mag;
 }