// ---------------------------------------------------------------------------- // 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()); }
// Returns a position randomly distributed inside a sphere of unit radius // centered at the origin. Orientation will be random and length will range // between 0 and 1 public static Vec3 RandomVectorInUnitRadiusSphere() { Vec3 v = new Vec3(); do { v.Set((Utilities.Random() * 2) - 1, (Utilities.Random() * 2) - 1, (Utilities.Random() * 2) - 1); }while (v.Length() >= 1); return(v); }
// ---------------------------------------------------------------------------- // 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); }
// if this position is outside sphere, push it back in by one diameter public Vec3 SphericalWraparound(Vec3 center, float radius) { Vec3 offset = this - center; float r = offset.Length(); if (r > radius) { return(this + ((offset / r) * radius * -2)); } else { return(this); } }
// ---------------------------------------------------------------------------- // Returns a position randomly distributed on a disk of unit radius // on the XZ (Y=0) plane, centered at the origin. Orientation will be // random and length will range between 0 and 1 public static Vec3 RandomVectorOnUnitRadiusXZDisk() { Vec3 v = new Vec3(); do { v.Set((Utilities.Random() * 2) - 1, 0, (Utilities.Random() * 2) - 1); } while (v.Length() >= 1); return v; }
// ---------------------------------------------------------------------------- // 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; }