예제 #1
0
        private double[] GetIntersectionsFromBook(Tuple4 origin, Tuple4 dir)
        {
            if (!Constants.EpsilonCompare(1.0, dir.Length()))
            {
                throw new ArgumentException("Direction should be normalized", nameof(dir));
            }

            var sphereToRay  = Tuple4.Subtract(origin, Tuple4.ZeroPoint);
            var a            = Tuple4.DotProduct(dir, dir);
            var b            = 2 * Tuple4.DotProduct(dir, sphereToRay);
            var c            = Tuple4.DotProduct(sphereToRay, sphereToRay) - 1.0;
            var discriminant = b * b - 4 * a * c;

            if (discriminant < 0.0)
            {
                return(null);
            }
            var discriminantSqrt = Math.Sqrt(discriminant);
            var t0 = (-b - discriminantSqrt) / (2 * a);
            var t1 = (-b + discriminantSqrt) / (2 * a);

            // Ray originates inside sphere
            // When t > 0 that is intersection in the direction of the ray
            // other intersection is in the opposite direction
            return(new double[] { t0, t1 });
        }
예제 #2
0
            public static IMatrix LookAtTransform(Tuple4 from, Tuple4 to, Tuple4 up)
            {
                var forward      = Tuple4.Normalize(Tuple4.Subtract(to, from));
                var upNormalized = Tuple4.Normalize(up);
                var left         = Tuple4.CrossProduct(forward, upNormalized);
                var trueUp       = Tuple4.CrossProduct(left, forward);

                var viewMatrix = new Matrix(new double[, ]
                {
                    { left.X, left.Y, left.Z, -Tuple4.DotProduct(left, from) },
                    { trueUp.X, trueUp.Y, trueUp.Z, -Tuple4.DotProduct(trueUp, from) },
                    { -forward.X, -forward.Y, -forward.Z, Tuple4.DotProduct(forward, from) },
                    { 0.0, 0.0, 0.0, 1.0 }
                });

                return(viewMatrix);

                /*
                 *  // Create a 4x4 orientation matrix from the left, up, and forward vectors
                 *  // This is transposed which is equivalent to performing an inverse
                 *  // if the matrix is orthonormalized (in this case, it is).
                 *  var orientation = new Matrix(new double[,]
                 *  {
                 *      {      left.X,     left.Y,     left.Z, 0.0 },
                 *      {    trueUp.X,   trueUp.Y,   trueUp.Z, 0.0 },
                 *      {  -forward.X, -forward.Y, -forward.Z, 0.0 },
                 *      {         0.0,        0.0,        0.0, 1.0 }
                 *  }, false);
                 *
                 *  // Create a 4x4 translation matrix.
                 *  // The eye position is negated which is equivalent
                 *  // to the inverse of the translation matrix.
                 *  var translation = Translation(-from.X, -from.Y, -from.Z);
                 *
                 *  // Combine the orientation and translation to compute
                 *  // the final view matrix. Note that the order of
                 *  // multiplication is reversed because the matrices
                 *  // are already inverted.
                 *  return Multiply(orientation, translation);
                 */
            }
예제 #3
0
            public static IMatrix EulerAnglesTransformDirectConstruction(Tuple4 from, double pitch, double yaw)
            {
                double cosPitch = Math.Cos(pitch);
                double sinPitch = Math.Sin(pitch);
                double cosYaw   = Math.Cos(yaw);
                double sinYaw   = Math.Sin(yaw);

                Tuple4 xaxis = new Tuple4(cosYaw, 0, -sinYaw, TupleFlavour.Vector);
                Tuple4 yaxis = new Tuple4(sinYaw * sinPitch, cosPitch, cosYaw * sinPitch, TupleFlavour.Vector);
                Tuple4 zaxis = new Tuple4(sinYaw * cosPitch, -sinPitch, cosPitch * cosYaw, TupleFlavour.Vector);

                var viewMatrix = new Matrix(new double[, ]
                {
                    { xaxis.X, xaxis.Y, xaxis.Z, -Tuple4.DotProduct(xaxis, from) },
                    { yaxis.X, yaxis.Y, yaxis.Z, -Tuple4.DotProduct(yaxis, from) },
                    { zaxis.X, zaxis.Y, zaxis.Z, -Tuple4.DotProduct(zaxis, from) },
                    { 0, 0, 0, 1 }
                });

                return(viewMatrix);
            }
예제 #4
0
        private double[] GetIntersections(Tuple4 origin, Tuple4 dir)
        {
            if (!Constants.EpsilonCompare(1.0, dir.Length()))
            {
                throw new ArgumentException("Direction should be normalized", nameof(dir));
            }

            var l   = Tuple4.Subtract(Center, origin);
            var tca = Tuple4.DotProduct(l, dir);
            var d2  = Tuple4.DotProduct(l, l) - tca * tca;

            if (d2 > radius2)
            {
                return(null);
            }
            var thc = Math.Sqrt(radius2 - d2);
            var t0  = tca - thc;
            var t1  = tca + thc;

            // Ray originates inside sphere
            // When t > 0 that is intersection in the direction of the ray
            // other intersection is in the opposite direction
            return(new double[] { t0, t1 });
        }