private double IntersectRayDisk(Disk disk, Vector O, Vector D) { O = new Vector(O.D1 - disk.Position.D1, O.D2 - disk.Position.D2, O.D3 - disk.Position.D3); if (disk.Rotation != null) { D = D.MultiplyMatrix(disk.Rotation.Rotation); O = O.MultiplyMatrix(disk.Rotation.Rotation); } var t = -O.D3 / D.D3; var x = D.D1 * t + O.D1; var y = D.D2 * t + O.D2; if (x * x / disk.A + y * y / disk.B < disk.R2) { return(t); } return(double.PositiveInfinity); }
private double IntersectRayTorus(Torus torus, Vector O, Vector D) { var o = O; var d = D; var r = torus.TubeRadius; var R = torus.SweptRadius; o = new Vector(o.D1 - torus.Position.D1, o.D2 - torus.Position.D2, o.D3 - torus.Position.D3); if (torus.Rotation != null) { d = d.MultiplyMatrix(torus.Rotation.Rotation); o = o.MultiplyMatrix(torus.Rotation.Rotation); } var intersectBox = IntersectRayBox(o, d.Invert(), torus.AroundBox); if (double.IsNaN(intersectBox) || double.IsPositiveInfinity(intersectBox)) { return(double.NaN); } var ox = o.D1; var oy = o.D2; var oz = o.D3; var dx = d.D1; var dy = d.D2; var dz = d.D3; var rPow2 = r * r; var RPow2 = R * R; var dyPow2 = dy * dy; var oyPow2 = oy * oy; // define the coefficients of the quartic equation var sum_d_sqrd = dx * dx + dyPow2 + dz * dz; var e = ox * ox + oyPow2 + oz * oz - RPow2 - rPow2; var f = ox * dx + oy * dy + oz * dz; var four_a_sqrd = 4.0 * RPow2; var coeffs = new[] { sum_d_sqrd *sum_d_sqrd, 4.0 *sum_d_sqrd *f, 2.0 *sum_d_sqrd *e + 4.0 *f *f + four_a_sqrd *dyPow2, 4.0 *f *e + 2.0 *four_a_sqrd *oy *dy, e *e - four_a_sqrd *(rPow2 - oyPow2) }; var solve = RealPolynomialRootFinder.FindRoots(coeffs); if (solve == null) { return(double.PositiveInfinity); } var min = double.PositiveInfinity; for (var i = 0; i < solve.Count; i++) { if (solve[i].IsReal() && solve[i].Real > 0.0001 && solve[i].Real < min) { min = solve[i].Real; } } return(min); }
private double IntersectRaySurface(Surface surface, Vector O, Vector D) { var origO = new Vector(O); var origD = new Vector(D); var a = surface.A; var b = surface.B; var c = surface.C; var d = surface.D; var e = surface.E; var f = surface.F; O = new Vector(O.D1 - surface.Position.D1, O.D2 - surface.Position.D2, O.D3 - surface.Position.D3); if (surface.Rotation != null) { D = D.MultiplyMatrix(surface.Rotation.Rotation); O = O.MultiplyMatrix(surface.Rotation.Rotation); } var d1 = D.D1; var d2 = D.D2; var d3 = D.D3; var o1 = O.D1; var o2 = O.D2; var o3 = O.D3; var p1 = 2 * a * d1 * o1 + 2 * b * d2 * o2 + 2 * c * d3 * o3 + d * d3 + d2 * e; var p2 = a * d1.Pow2() + b * d2.Pow2() + c * d3.Pow2(); var p3 = a * o1.Pow2() + b * o2.Pow2() + c * o3.Pow2() + d * o3 + e * o2 + f; var p4 = Math.Sqrt(p1.Pow2() - 4 * p2 * p3); //division by zero if (Math.Abs(p2) < 1e-20) { var t = -p3 / p1; return(t); } var min = double.PositiveInfinity; var max = double.PositiveInfinity; var t1 = (-p1 - p4) / (2 * p2); var t2 = (-p1 + p4) / (2 * p2); var epsilon = 1e-4; if (t1 > epsilon && t1 < min) { min = t1; max = t2; } if (t2 > epsilon && t2 < min) { min = t2; max = t1; } var vMin = new Vector(surface.XMin, surface.YMin, surface.ZMin); var vMax = new Vector(surface.XMax, surface.YMax, surface.ZMax); if (!CheckSurfaceEdges(origD, origO, ref min, ref max, vMin, vMax, epsilon)) { return(double.PositiveInfinity); } return(min); }