public static bool IsPlaneIntersectingCone(Vect3 planeNormal, Vect3 planePoint, Vect3 conePosition, Vect3 coneAxis, double coneAxisLength, double coneCosPhi) { double len; //try "bending" axis towards plane normal Vect3 q = conePosition + coneAxis * coneAxisLength; Vect3 qx = planeNormal.ProjectOn(coneAxis); Vect3 p = qx - planeNormal; if (System.Math.Abs(p.QuadLength() - 0) < Constants.EPS) { // axis equals plane normal p = coneAxis; len = coneAxisLength; } else { //bend axis towards plane normal as far as sinPhi allows p = p.Normalize(); q = q + (p * coneAxisLength * System.Math.Sin(System.Math.Acos(coneCosPhi))); q -= conePosition; len = q.Length(); p = q / len; } double d = RayPlane.GetHitPointRayPlaneDistance(conePosition, p, planePoint, planeNormal); return(d < len); }
public static bool IsRayOriginatingInSphere(Vect3 rayOrigin, Vect3 rayDirection, Vect3 sphereCenter, double sphereRadius) { Vect3 tmp = sphereCenter - rayOrigin; return(tmp.QuadLength() < sphereRadius * sphereRadius); }
public void DotProductInverseVector() { var rd = new Random(); var vect1 = new Vect3 { X = rd.NextDouble(), Y = rd.NextDouble(), Z = rd.NextDouble() }; Assert.That(vect1 * (vect1 * -1), Is.EqualTo(-vect1.QuadLength())); }
/** * Refraction * * @param incoming incoming vector * @param normal normal of the reflectio area * @param outgoing result of the computation */ public static Vect3 RefractOn(this Vect3 incoming, Vect3 normal, double refractionIndex) { //test implementation - working but propably slow Vect3 result = incoming.ProjectOnNormal(normal); result = result / refractionIndex; double quadLen = result.QuadLength(); if (quadLen >= 1) //total reflection { result = incoming.ReflectOn(normal); } else { result = result + (normal * -System.Math.Sqrt(1 - quadLen)); result = result.Normalize(); } return(result); }
public static bool IsAreaIntersectingCone(Vect3 planeNormal, Vect3 planePoint, double areaWidthHalf, Vect3 conePosition, Vect3 coneAxis, double coneAxisLength, double coneCosPhi) { double len; //try "bending" axis towards plane normal Vect3 q = conePosition + coneAxis * coneAxisLength; Vect3 qx = planeNormal.ProjectOn(coneAxis); Vect3 p = qx - planeNormal; if (System.Math.Abs(p.QuadLength() - 0) < Constants.EPS) { // axis equals plane normal p = coneAxis; len = coneAxisLength; } else { //bend axis towards plane normal as far as sinPhi allows p = p.Normalize(); q = q + (p * coneAxisLength * System.Math.Sin(System.Math.Acos(coneCosPhi))); q -= conePosition; len = q.Length(); p = q / len; } double d = RayPlane.GetHitPointRayPlaneDistance(conePosition, p, planePoint, planeNormal); if (d < len) { //check if Hitpoint is in the +/-width/2 - area of the plane p = conePosition + p * d; return (System.Math.Abs(p.X - planePoint.X) < areaWidthHalf * 2 && System.Math.Abs(p.Y - planePoint.Y) < areaWidthHalf * 2 && System.Math.Abs(p.Z - planePoint.Z) < areaWidthHalf * 2); } return(false); }
public static Octree BuildTree(Vect3 center, IList <I3DObject> objects) { double maxQuadDist = 0; Log.Debug("Building octree... "); foreach (I3DObject o in objects) { Sphere s = o.GetBoundingSphere(); if (s != null) { Vect3 dist = center - s.Position; double qdist = s.Radius; if (double.IsInfinity(qdist) || Double.IsNaN(qdist)) { throw new Exception("Invalid BoundingSphere: " + s + " from " + o); } qdist = qdist * qdist + dist.QuadLength(); if (maxQuadDist < qdist) { maxQuadDist = qdist; } } } /** * Workaround: *2.1 instead of *2, because rays must always start inside an octree for RayPath. * To fix this problem, a RayPath should allow ray-origins outside the octree, but this would need * an additional ray-cube intersection test which is currently not implemented. Another downside of * this is that the camera must always be located inside the octree - it must not be moved outside. */ double sizeHint = System.Math.Sqrt(maxQuadDist) * 2.1; Sw.Restart(); Octree t; while (true) { t = new Octree(center, sizeHint); foreach (I3DObject o in objects) { if (!t.Root.Insert(o, o.GetBoundingSphere())) { sizeHint *= 2; Log.Warn("Warning - resize needed!"); goto cont; } } break; cont: { } } t.GetRoot().Compress(); Sw.Stop(); Log.Debug(string.Format("{0} ms\n", Sw.ElapsedMilliseconds)); Log.Debug(string.Format(" - contains {0} of {1} elements ({2:0.##}%)", t.GetRoot().GetSize(), objects.Count, t.GetRoot().GetSize() / (float)objects.Count * 100)); Log.Debug(" - avg depth: " + t.GetAverageObjectDepth()); Log.Debug(" - node count: " + t.GetRoot().GetNodeCount()); Log.Debug(" - objects per node: " + t.GetRoot().GetSize() / (float)t.GetRoot().GetNodeCount()); return(t); }