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 }); }
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); */ }
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); }
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 }); }