Ejemplo n.º 1
0
            public double[] MakeFromX(FVector XAxis)
            {
                double[] mt   = new double[9];
                FVector  NewX = XAxis.GetSafeNormal();

                // try to use up if possible
                FVector UpVector = new FVector(0, 0, 1.0);// (Math.Abs(NewX.Z) < (1.0 - KINDA_SMALL_NUMBER)) ? FVector(0, 0, 1.f) : FVector(1.f, 0, 0);

                FVector NewY = (UpVector.CrossProduct(NewX)).GetSafeNormal();
                FVector NewZ = NewX.CrossProduct(NewY);

                //FRotator Rotator = new FRotator(Math.Atan2(NewX.Z, Math.Sqrt(NewX.X * NewX.X + NewX.Y * NewX.Y)) * 180.0 / PI,
                //                    Math.Atan2(XAxis.Y, XAxis.X) * 180.0 / PI,
                //                    0);

                //const FVector SYAxis = FRotationMatrix(Rotator).GetScaledAxis(EAxis::Y);
                //Rotator.Roll = FMath::Atan2(ZAxis | SYAxis, YAxis | SYAxis) * 180.f / PI;
                mt[0] = NewX.X;
                mt[1] = NewX.Y;
                mt[2] = NewX.Z;
                mt[3] = NewY.X;
                mt[4] = NewY.Y;
                mt[5] = NewY.Z;
                mt[6] = NewZ.X;
                mt[7] = NewZ.Y;
                mt[8] = NewZ.Z;

                return(mt);
            }
Ejemplo n.º 2
0
        /// <summary>
        /// Returns a random unit vector, uniformly distributed, within the specified cone.
        /// </summary>
        /// <param name="dir">The center direction of the cone</param>
        /// <param name="horizontalConeHalfAngleRad">Horizontal half-angle of cone, in radians.</param>
        /// <param name="verticalConeHalfAngleRad">Vertical half-angle of cone, in radians.</param>
        /// <returns>Normalized vector within the specified cone.</returns>
        public FVector VRandCone(FVector dir, float horizontalConeHalfAngleRad, float verticalConeHalfAngleRad)
        {
            if ((verticalConeHalfAngleRad > 0.0f) && (horizontalConeHalfAngleRad > 0.0f))
            {
                float randU = FRand();
                float randV = FRand();

                // Get spherical coords that have an even distribution over the unit sphere
                // Method described at http://mathworld.wolfram.com/SpherePointPicking.html
                float theta = 2.0f * FMath.PI * randU;
                float phi   = FMath.Acos((2.0f * randV) - 1.0f);

                // restrict phi to [0, ConeHalfAngleRad]
                // where ConeHalfAngleRad is now a function of Theta
                // (specifically, radius of an ellipse as a function of angle)
                // function is ellipse function (x/a)^2 + (y/b)^2 = 1, converted to polar coords
                float coneHalfAngleRad = FMath.Square(FMath.Cos(theta) / verticalConeHalfAngleRad) + FMath.Square(FMath.Sin(theta) / horizontalConeHalfAngleRad);
                coneHalfAngleRad = FMath.Sqrt(1.0f / coneHalfAngleRad);

                // clamp to make a cone instead of a sphere
                phi = FMath.Fmod(phi, coneHalfAngleRad);

                // get axes we need to rotate around
                FMatrix dirMat = FMatrix.CreateRotation(dir.Rotation());
                // note the axis translation, since we want the variation to be around X
                FVector dirZ = dirMat.GetUnitAxis(EAxis.X);
                FVector dirY = dirMat.GetUnitAxis(EAxis.Y);

                FVector result = dir.RotateAngleAxis(phi * 180.0f / FMath.PI, dirY);
                result = result.RotateAngleAxis(theta * 180.0f / FMath.PI, dirZ);

                // ensure it's a unit vector (might not have been passed in that way)
                result = result.GetSafeNormal();

                return(result);
            }
            else
            {
                return(dir.GetSafeNormal());
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Returns a random unit vector, uniformly distributed, within the specified cone.
        /// </summary>
        /// <param name="dir">The center direction of the cone</param>
        /// <param name="coneHalfAngleRad">Half-angle of cone, in radians.</param>
        /// <returns>Normalized vector within the specified cone.</returns>
        public FVector VRandCone(FVector dir, float coneHalfAngleRad)
        {
            if (coneHalfAngleRad > 0.0f)
            {
                float randU = FRand();
                float randV = FRand();

                // Get spherical coords that have an even distribution over the unit sphere
                // Method described at http://mathworld.wolfram.com/SpherePointPicking.html
                float theta = 2.0f * FMath.PI * randU;
                float phi   = FMath.Acos((2.0f * randV) - 1.0f);

                // restrict phi to [0, ConeHalfAngleRad]
                // this gives an even distribution of points on the surface of the cone
                // centered at the origin, pointing upward (z), with the desired angle
                phi = FMath.Fmod(phi, coneHalfAngleRad);

                // get axes we need to rotate around
                FMatrix dirMat = FMatrix.CreateRotation(dir.Rotation());
                // note the axis translation, since we want the variation to be around X
                FVector dirZ = dirMat.GetUnitAxis(EAxis.X);
                FVector dirY = dirMat.GetUnitAxis(EAxis.Y);

                FVector result = dir.RotateAngleAxis(phi * 180.0f / FMath.PI, dirY);
                result = result.RotateAngleAxis(theta * 180.0f / FMath.PI, dirZ);

                // ensure it's a unit vector (might not have been passed in that way)
                result = result.GetSafeNormal();

                return(result);
            }
            else
            {
                return(dir.GetSafeNormal());
            }
        }