static float CalculateMidPercent(const SplineControlNode& start, const SplineControlNode& end) { // The mid value we called 'k' in the dual cubic documentation. // It's between 0~1 and determines where the start and end cubics are joined // along the x-axis. const Range valid_range = CalculateValidMidRange(start, end); // Return the part of the range closest to the half-way mark. This seems to // generate the smoothest looking curves. const float mid_unclamped = valid_range.Clamp(0.5f); // Clamp away from 0 and 1. The math requires the mid node to be strictly // between 0 and 1. If we get to close to 0 or 1, some divisions are going to // explode and we'll lose numerical precision. const float mid = mathfu::Clamp(mid_unclamped, kMinMidPercent, kMaxMidPercent); return mid; }
// Clamping values inside the range should result in the same value. TEST_F(RangeTests, Clamp_Border) { const Range zero_one(0.0f, 1.0f); EXPECT_EQ(0.0f, zero_one.Clamp(0.0f)); EXPECT_EQ(1.0f, zero_one.Clamp(1.0f)); }
// Clamping values inside the range should result in the same value. TEST_F(RangeTests, Clamp_Inside) { const Range zero_one(0.0f, 1.0f); EXPECT_EQ(0.5f, zero_one.Clamp(0.5f)); EXPECT_EQ(0.9999999f, zero_one.Clamp(0.9999999f)); }
// Clamping values to the full range should always return the original value. TEST_F(RangeTests, Clamp_ToInfinity) { const Range full(-kInf, kInf); EXPECT_EQ(kInf, full.Clamp(kInf)); EXPECT_EQ(1.0f, full.Clamp(1.0f)); EXPECT_EQ(-kInf, full.Clamp(-kInf)); }
// Passing infinity into a range should clamp fine. TEST_F(RangeTests, Clamp_Infinity) { const Range zero_one(0.0f, 1.0f); EXPECT_EQ(1.0f, zero_one.Clamp(kInf)); EXPECT_EQ(0.0f, zero_one.Clamp(-kInf)); }
// Clamping values inside the range should result in the same value. TEST_F(RangeTests, Clamp_Outside) { const Range zero_one(0.0f, 1.0f); EXPECT_EQ(0.0f, zero_one.Clamp(-1.0f)); EXPECT_EQ(1.0f, zero_one.Clamp(1.0000001f)); }