float3 Triangle::RandomPointInside(LCG &rng) const { float epsilon = 1e-3f; ///@todo rng.Float() returns [0,1[, but to be completely uniform, we'd need [0,1] here. float s = rng.Float(epsilon, 1.f - epsilon);//1e-2f, 1.f - 1e-2f); float t = rng.Float(epsilon, 1.f - epsilon);//1e-2f, 1.f - 1e-2f if (s + t >= 1.f) { s = 1.f - s; t = 1.f - t; } #ifdef MATH_ASSERT_CORRECTNESS float3 pt = Point(s, t); float2 uv = BarycentricUV(pt); assert(uv.x >= 0.f); assert(uv.y >= 0.f); assert(uv.x + uv.y <= 1.f); float3 uvw = BarycentricUVW(pt); assert(uvw.x >= 0.f); assert(uvw.y >= 0.f); assert(uvw.z >= 0.f); assert(EqualAbs(uvw.x + uvw.y + uvw.z, 1.f)); #endif return Point(s, t); }
float3 Triangle::ClosestPointToTriangleEdge(const LineSegment &lineSegment, float *outU, float *outV, float *outD) const { ///@todo Optimize! // The line is parallel to the triangle. float d1, d2, d3; float3 pt1 = Edge(0).ClosestPoint(lineSegment, 0, &d1); float3 pt2 = Edge(1).ClosestPoint(lineSegment, 0, &d2); float3 pt3 = Edge(2).ClosestPoint(lineSegment, 0, &d3); float dist1 = pt1.DistanceSq(lineSegment.GetPoint(d1)); float dist2 = pt2.DistanceSq(lineSegment.GetPoint(d2)); float dist3 = pt3.DistanceSq(lineSegment.GetPoint(d3)); if (dist1 <= dist2 && dist1 <= dist3) { if (outU) *outU = BarycentricUV(pt1).x; if (outV) *outV = BarycentricUV(pt1).y; if (outD) *outD = d1; return pt1; } else if (dist2 <= dist3) { if (outU) *outU = BarycentricUV(pt2).x; if (outV) *outV = BarycentricUV(pt2).y; if (outD) *outD = d2; return pt2; } else { if (outU) *outU = BarycentricUV(pt3).x; if (outV) *outV = BarycentricUV(pt3).y; if (outD) *outD = d3; return pt3; } }