// dot(rayDir, rayDir) * t^2 + 2*t*dot(rayDir, rayOrig-center) + dot(rayOrig-center, rayOrig-center) - R*R=0 public bool Hit(Ray ray, float tMin, float tMax, ref HitRecord record) { float a = ray.Direction.LengthSquared; // dot(rayDir, rayDir) Vec3 temp = new Vec3(); Vec3.Subtract(ray.Origin, this.Center, temp); float b = 2 * ray.Direction.Dot(temp); //2*dot(rayDir, rayOrig-center) float c = temp.LengthSquared - this.Radius * this.Radius; //dot(rayOrig-center, rayOrig-center) - R*R if (!PolyUtils.HasRealRoot(a, b, c)) { // No hit return(false); } // Check first root for hit float firstRoot = PolyUtils.FirstRoot(a, b, c); if (firstRoot > tMin && firstRoot < tMax) { record.T = firstRoot; record.Point = ray.PointAt(firstRoot); Vec3.Subtract(record.Point, this.Center, temp); record.Normal = temp / this.Radius; record.Material = this.Material; return(true); } // Check second root for hit float secondRoot = PolyUtils.SecondRoot(a, b, c); if (secondRoot > tMin && secondRoot < tMax) { record.T = secondRoot; record.Point = ray.PointAt(secondRoot); Vec3.Subtract(record.Point, this.Center, temp); record.Normal = temp / this.Radius; record.Material = this.Material; return(true); } return(false); }
public bool Hit(Ray ray, float tMin, float tMax, ref HitRecord record) { var originRecBase = TransformUtils.OrthogonalBaseChange(ray.Origin, this.u, this.v, this.normal); var dirRecBase = TransformUtils.OrthogonalBaseChange(ray.Direction, this.u, this.v, this.normal); float t = (this.z - originRecBase.Z) / dirRecBase.Z; if (t < tMin || t > tMax) { return(false); } float x = originRecBase.X + t * dirRecBase.X; float y = originRecBase.Y + t * dirRecBase.Y; if (x < this.x0 || x > this.x1 || y < this.y0 || y > this.y1) { return(false); } record.T = t; record.Material = this.Material; record.Point = ray.PointAt(t); record.Normal = this.normal; return(true); }