// ---------------------------------------------------------------------------- // Returns the distance between a point and a line. The line is defined in // terms of a point on the line ("lineOrigin") and a UNIT vector parallel to // the line ("lineUnitTangent") public static float DistanceFromLine(Vec3 point, Vec3 lineOrigin, Vec3 lineUnitTangent) { Vec3 offset = point - lineOrigin; Vec3 perp = offset.PerpendicularComponent(lineUnitTangent); return(perp.Length()); }
// ---------------------------------------------------------------------------- // used by limitMaxDeviationAngle / limitMinDeviationAngle below public static Vec3 LimitDeviationAngleUtility(bool insideOrOutside, Vec3 source, float cosineOfConeAngle, Vec3 basis) { // immediately return zero length input vectors float sourceLength = source.Length(); if (sourceLength == 0) { return(source); } // measure the angular diviation of "source" from "basis" Vec3 direction = source / sourceLength; float cosineOfSourceAngle = direction.Dot(basis); // Simply return "source" if it already meets the angle criteria. // (note: we hope this top "if" gets compiled out since the flag // is a constant when the function is inlined into its caller) if (insideOrOutside) { // source vector is already inside the cone, just return it if (cosineOfSourceAngle >= cosineOfConeAngle) { return(source); } } else { // source vector is already outside the cone, just return it if (cosineOfSourceAngle <= cosineOfConeAngle) { return(source); } } // find the portion of "source" that is perpendicular to "basis" Vec3 perp = source.PerpendicularComponent(basis); // normalize that perpendicular Vec3 unitPerp = perp.Normalize(); // construct a new vector whose length equals the source vector, // and lies on the intersection of a plane (formed the source and // basis vectors) and a cone (whose axis is "basis" and whose // angle corresponds to cosineOfConeAngle) float perpDist = (float)Math.Sqrt(1 - (cosineOfConeAngle * cosineOfConeAngle)); Vec3 c0 = basis * cosineOfConeAngle; Vec3 c1 = unitPerp * perpDist; return((c0 + c1) * sourceLength); }
// ---------------------------------------------------------------------------- // used by limitMaxDeviationAngle / limitMinDeviationAngle below public static Vec3 LimitDeviationAngleUtility(bool insideOrOutside, Vec3 source, float cosineOfConeAngle, Vec3 basis) { // immediately return zero length input vectors float sourceLength = source.Length(); if (sourceLength == 0) return source; // measure the angular diviation of "source" from "basis" Vec3 direction = source / sourceLength; float cosineOfSourceAngle = direction.Dot(basis); // Simply return "source" if it already meets the angle criteria. // (note: we hope this top "if" gets compiled out since the flag // is a constant when the function is inlined into its caller) if (insideOrOutside) { // source vector is already inside the cone, just return it if (cosineOfSourceAngle >= cosineOfConeAngle) return source; } else { // source vector is already outside the cone, just return it if (cosineOfSourceAngle <= cosineOfConeAngle) return source; } // find the portion of "source" that is perpendicular to "basis" Vec3 perp = source.PerpendicularComponent(basis); // normalize that perpendicular Vec3 unitPerp = perp.Normalize(); // construct a new vector whose length equals the source vector, // and lies on the intersection of a plane (formed the source and // basis vectors) and a cone (whose axis is "basis" and whose // angle corresponds to cosineOfConeAngle) float perpDist = (float)Math.Sqrt(1 - (cosineOfConeAngle * cosineOfConeAngle)); Vec3 c0 = basis * cosineOfConeAngle; Vec3 c1 = unitPerp * perpDist; return (c0 + c1) * sourceLength; }