RNScalar R3PointLight:: RadiusOfInfluence(RNScalar intensity_threshhold) const { // Return distance beyond which intensity is below threshold // kq*d^2 + kl*d + (kc - 1/a) = 0 (use quadratic formula) if (RNIsZero(Intensity())) return 0.0; if (RNIsZero(intensity_threshhold)) return RN_INFINITY; RNScalar A = quadratic_attenuation; RNScalar B = linear_attenuation; RNScalar C = constant_attenuation - Intensity() / intensity_threshhold; RNScalar radius = (-B + sqrt(B*B - 4.0*A*C)) / (2.0*A); return radius; }
void R3Matrix:: Invert(void) { // Compute determinant RNScalar det = Determinant(); if (RNIsZero(det, 1E-8)) { RNWarning("Unable to invert matrix with zero determinant"); return; } // Copy values RNScalar m00 = m[0][0]; RNScalar m01 = m[0][1]; RNScalar m02 = m[0][2]; RNScalar m10 = m[1][0]; RNScalar m11 = m[1][1]; RNScalar m12 = m[1][2]; RNScalar m20 = m[2][0]; RNScalar m21 = m[2][1]; RNScalar m22 = m[2][2]; // Compute inverse matrix m[0][0] = R3MatrixDet2(m11, m12, m21, m22)/det; m[0][1] = R3MatrixDet2(m02, m01, m22, m21)/det; m[0][2] = R3MatrixDet2(m01, m02, m11, m12)/det; m[1][0] = R3MatrixDet2(m12, m10, m22, m20)/det; m[1][1] = R3MatrixDet2(m00, m02, m20, m22)/det; m[1][2] = R3MatrixDet2(m02, m00, m12, m10)/det; m[2][0] = R3MatrixDet2(m10, m11, m20, m21)/det; m[2][1] = R3MatrixDet2(m01, m00, m21, m20)/det; m[2][2] = R3MatrixDet2(m00, m01, m10, m11)/det; }
const R3Point R3Sphere:: FurthestPoint(const R3Point& point) const { // Return furthest point in sphere if (radius <= 0) return center; R3Vector v = point - Center(); RNLength d = v.Length(); if (RNIsZero(d)) return R3Point(center[0] + radius, center[1], center[2]); else return center - radius * v / d; }
RNScalar R3PointLight:: IntensityAtPoint(const R3Point& point) const { // Return intensity at point RNLength d = R3Distance(point, position); RNScalar denom = constant_attenuation; denom += d * linear_attenuation; denom += d * d * quadratic_attenuation; if (RNIsZero(denom)) return Intensity(); else return (Intensity() / denom); }
const RNBoolean R3Point:: Collinear(const R3Point& point1, const R3Point& point2) const { // Check if two of points are same if ((*this == point1) || (*this == point2) || (point1 == point2)) return TRUE; /// Check if three points are collinear R3Vector v = point1 - *this; v.Cross(point1 - point2); if (RNIsZero(v.Length())) return TRUE; return FALSE; }
RNLength R2Distance(const R2Point& point, const R2Span& span) { // Check span if (RNIsZero(span.Length())) return R2Distance(point, span.Start()); // Check if start point is closest R2Vector v1 = point - span.Start(); RNScalar dir1 = v1.Dot(span.Vector()); if (RNIsNegative(dir1)) return v1.Length(); // Check if end point is closest R2Vector v2 = point - span.End(); RNScalar dir2 = v2.Dot(span.Vector()); if (RNIsPositive(dir2)) return v2.Length(); // Return distance from point to span line return R2Distance(point, span.Line()); }
void R4Matrix:: Invert(void) { // Copy matrix into local variables RNScalar Ma, Mb, Mc, Md, Me, Mf, Mg, Mh, Mi, Mj, Mk, Ml, Mm, Mn, Mo, Mp; Ma = m[0][0]; Mb = m[0][1]; Mc = m[0][2]; Md = m[0][3]; Me = m[1][0]; Mf = m[1][1]; Mg = m[1][2]; Mh = m[1][3]; Mi = m[2][0]; Mj = m[2][1]; Mk = m[2][2]; Ml = m[2][3]; Mm = m[3][0]; Mn = m[3][1]; Mo = m[3][2]; Mp = m[3][3]; // Compute sub-determinants and determinant RNScalar a1 = R4MatrixDet3(Mf, Mg, Mh, Mj, Mk, Ml, Mn, Mo, Mp); RNScalar a2 = R4MatrixDet3(Me, Mg, Mh, Mi, Mk, Ml, Mm, Mo, Mp); RNScalar a3 = R4MatrixDet3(Me, Mf, Mh, Mi, Mj, Ml, Mm, Mn, Mp); RNScalar a4 = R4MatrixDet3(Me, Mf, Mg, Mi, Mj, Mk, Mm, Mn, Mo); RNScalar det = Ma*a1 - Mb*a2 + Mc*a3 - Md*a4; if (RNIsZero(det, 1E-8)) { RNWarning("Unable to invert matrix with zero determinant"); return; } // Compute inverse matrix m[0][0] = (a1)/det; m[1][0] = -(a2)/det; m[2][0] = (a3)/det; m[3][0] = -(a4)/det; m[0][1] = -(R4MatrixDet3(Mb, Mc, Md, Mj, Mk, Ml, Mn, Mo, Mp))/det; m[1][1] = (R4MatrixDet3(Ma, Mc, Md, Mi, Mk, Ml, Mm, Mo, Mp))/det; m[2][1] = -(R4MatrixDet3(Ma, Mb, Md, Mi, Mj, Ml, Mm, Mn, Mp))/det; m[3][1] = (R4MatrixDet3(Ma, Mb, Mc, Mi, Mj, Mk, Mm, Mn, Mo))/det; m[0][2] = (R4MatrixDet3(Mb, Mc, Md, Mf, Mg, Mh, Mn, Mo, Mp))/det; m[1][2] = -(R4MatrixDet3(Ma, Mc, Md, Me, Mg, Mh, Mm, Mo, Mp))/det; m[2][2] = (R4MatrixDet3(Ma, Mb, Md, Me, Mf, Mh, Mm, Mn, Mp))/det; m[3][2] = -(R4MatrixDet3(Ma, Mb, Mc, Me, Mf, Mg, Mm, Mn, Mo))/det; m[0][3] = -(R4MatrixDet3(Mb, Mc, Md, Mf, Mg, Mh, Mj, Mk, Ml))/det; m[1][3] = (R4MatrixDet3(Ma, Mc, Md, Me, Mg, Mh, Mi, Mk, Ml))/det; m[2][3] = -(R4MatrixDet3(Ma, Mb, Md, Me, Mf, Mh, Mi, Mj, Ml))/det; m[3][3] = (R4MatrixDet3(Ma, Mb, Mc, Me, Mf, Mg, Mi, Mj, Mk))/det; }
RNBoolean R3Perpendicular(const R3Vector& vector1, const R3Vector& vector2) { // Normalized vectors ??? // Return whether vector1 and vector2 are perpendicular return RNIsZero(vector1.Dot(vector2)); }
const RNBoolean R3Sphere:: IsPoint(void) const { // A sphere only lies on a single point if it has radius zero return RNIsZero(radius); }
RNBoolean R3Contains(const R3Line& line, const R3Point& point) { // Return whether line contains point ??? return RNIsZero(R3Distance(line, point)); }
RNBoolean R3Contains(const R3Plane& plane, const R3Point& point) { // Return whether plane contains point return RNIsZero(R3SignedDistance(plane, point)); }
RNBoolean R3Contains(const R3Span& span, const R3Point& point) { // Return whether span contains point ??? if (span.IsPoint()) return R3Contains(span.Start(), point); else return RNIsZero(R3Distance(span, point)); }
RNBoolean R3Contains(const R3Ray& ray, const R3Point& point) { // Return whether ray contains point ??? if (ray.IsZero()) return FALSE; else return RNIsZero(R3Distance(ray, point)); }