/// <summary>Returns the determinant of m. </summary>
 protected float determinant(dmat3 m)
 {
     throw _invalidAccess;
 }
 /// <summary>
 /// Returns a matrix that is the transpose of m. 
 /// The input matrix m is not modified.
 /// </summary>
 protected dmat3 transpose(dmat3 m)
 {
     throw _invalidAccess;
 }
Example #3
0
        /// <inheritdoc />
        public double RayIntersect(Ray ray)
        {
            dvec3 rayStart     = ray.StartPosition;
            dvec3 rayDirection = ray.Direction;

            DebugUtil.AssertAllFinite(rayStart, nameof(rayStart));
            DebugUtil.AssertAllFinite(rayDirection, nameof(rayDirection));

            // Since we raytrace only using a cylindrical surface that is horizontal and at the origin, we
            // first shift and rotate the ray such that we get the right orientation:
            dvec3 start = CenterCurve.GetStartPosition();
            dvec3 end   = CenterCurve.GetEndPosition();

            DebugUtil.AssertAllFinite(start, nameof(start));
            DebugUtil.AssertAllFinite(end, nameof(end));

            dvec3 tangent  = CenterCurve.GetTangentAt(0.0).Normalized;
            dvec3 normal   = CenterCurve.GetNormalAt(0.0).Normalized;
            dvec3 binormal = CenterCurve.GetBinormalAt(0.0).Normalized;

            DebugUtil.AssertAllFinite(tangent, nameof(tangent));
            DebugUtil.AssertAllFinite(normal, nameof(normal));
            DebugUtil.AssertAllFinite(binormal, nameof(binormal));

            double length = dvec3.Distance(start, end);

            DebugUtil.AssertFinite(length, nameof(length));

            // CenterCurve is guaranteed to be a LineSegment, since the base property CenterCurve is masked by this
            // class' CenterCurve property that only accepts a LineSegment, and similarly this class' constructor only
            // accepts a LineSegment. The following mathematics, which assumes that the central axis is a line segment,
            // is therefore valid.

            dmat3 rotationMatrix = new dmat3(normal, binormal, tangent / length).Transposed;

            dvec3 rescaledRay  = rotationMatrix * (rayStart - start);
            dvec3 newDirection = rotationMatrix * rayDirection.Normalized;


            double x0 = rescaledRay.x;
            double y0 = rescaledRay.y;
            double z0 = rescaledRay.z;

            double a = newDirection.x;
            double b = newDirection.y;
            double c = newDirection.z;

            // Raytrace using a cylindrical surface equation x^2 + y^2. The parameters in the following line
            // represent the coefficients of the expanded cylindrical surface equation, after the substitution
            // x = x_0 + a t and y = y_0 + b t:
            QuarticFunction surfaceFunction = new QuarticFunction(x0 * x0 + y0 * y0, 2.0 * (x0 * a + y0 * b), a * a + b * b, 0.0, 0.0);

            IEnumerable <double> intersections = Radius.SolveRaytrace(surfaceFunction, z0, c);

            // The previous function returns a list of intersection distances. The value closest to 0.0f represents the
            // closest intersection point.
            double minimum = Single.PositiveInfinity;

            foreach (double i in intersections)
            {
                // Calculate the 3d point at which the ray intersects the cylinder:
                dvec3 intersectionPoint = rayStart + i * rayDirection;

                // Find the closest point to the intersectionPoint on the centerLine.
                // Get the vector v from the start of the cylinder to the intersection point:
                dvec3 v = intersectionPoint - start;

                // ...And project this vector onto the center line:
                double t = -dvec3.Dot(intersectionPoint, tangent * length) / (length * length);

                // Now we have the parameter t on the surface of the SymmetricCylinder at which the ray intersects.

                // Find the angle to the normal of the centerLine, so that we can determine whether the
                // angle is within the bound of the pie-slice at position t:
                dvec3  centerLineNormal   = CenterCurve.GetNormalAt(t);
                dvec3  centerLineBinormal = CenterCurve.GetBinormalAt(t);
                dvec3  d = intersectionPoint - CenterCurve.GetPositionAt(t);
                double correctionShift = Math.Sign(dvec3.Dot(d, centerLineBinormal));
                double phi             = (correctionShift * Math.Acos(dvec3.Dot(d, centerLineNormal))) % (2.0 * Math.PI);

                // Determine if the ray is inside the pie-slice of the cylinder that is being displayed,
                // otherwise discard:
                if (phi > StartAngle.GetValueAt(t) && phi < EndAngle.GetValueAt(t) && i >= 0.0)
                {
                    minimum = Math.Sign(i) * Math.Min(Math.Abs(minimum), Math.Abs(i));
                }
            }

            return(minimum);
        }
 /// <summary>
 /// Multiply matrix x by matrix y component-wise, i.e., result[i][j] is the scalar product of x[i][j] and y[i][j].
 /// Note: to get linear algebraic matrix multiplication, use the multiply operator (*).
 /// </summary>
 protected dmat3 matrixCompMult(dmat3 x, dmat3 y)
 {
     throw _invalidAccess;
 }
Example #5
0
 /// <summary>
 /// Returns a matrix that is the transpose of m.
 /// The input matrix m is not modified.
 /// </summary>
 protected dmat3 transpose(dmat3 m)
 {
     throw _invalidAccess;
 }
Example #6
0
 /// <summary>Returns the determinant of m. </summary>
 protected double determinant(dmat3 m)
 {
     throw _invalidAccess;
 }
Example #7
0
 /// <summary>
 /// Multiply matrix x by matrix y component-wise, i.e., result[i][j] is the scalar product of x[i][j] and y[i][j].
 /// Note: to get linear algebraic matrix multiplication, use the multiply operator (*).
 /// </summary>
 protected dmat3 matrixCompMult(dmat3 x, dmat3 y)
 {
     throw _invalidAccess;
 }
Example #8
0
 /// <summary>initialized the matrix with the upperleft part of m
 /// sets the lower right diagonal component(s) to 1, everything else to 0</summary>
 public dmat4(dmat3 m)
 {
     throw _invalidAccess;
 }
 /// <summary>Returns the determinant of m. </summary>
 protected double determinant(dmat3 m)
 {
     throw _invalidAccess;
 }
 /// <summary>initialized the matrix with the upperleft part of m
 /// sets the lower right diagonal component(s) to 1, everything else to 0</summary>
 public dmat4x3(dmat3 m)
 {
     throw _invalidAccess;
 }
 /// <summary>initialized the matrix with the upperleft part of m
 /// sets the lower right diagonal component(s) to 1, everything else to 0</summary>
 public dmat3x4(dmat3 m)
 {
     throw _invalidAccess;
 }