bool CFuzzyMembershipFunction::Intersection (const CFuzzyElement& a1, const CFuzzyElement& a2, const CFuzzyElement& b1, const CFuzzyElement& b2, CFuzzyElement* pPoint) { if (!pPoint) { return false; } double X1 = double(a1.GetValue()); double X2 = double(a2.GetValue()); double X3 = double(b1.GetValue()); double X4 = double(b2.GetValue()); double Y1 = a1.GetMembership(); double Y2 = a2.GetMembership(); double Y3 = b1.GetMembership(); double Y4 = b2.GetMembership(); double Numerator; double Denominator; double Y; double X; double M; double B; double Ua; Denominator = ((Y4 - Y3) * (X2 - X1)) - ((X4 - X3) * (Y2 - Y1)); if (fabs(Denominator) <= DBL_EPSILON) { // Since denominator is zero, we either have parallel or coincident lines. return false; } Numerator = ((X4 - X3) * (Y1 - Y3)) - ((Y4 - Y3) * (X1 - X3)); Ua = Numerator / Denominator; X = X1 + (Ua * (X2 - X1)); // Check line segment A if ((long(X) < a1.GetValue()) || (a2.GetValue() < long(X))) { // The line intersection is not within segment A, no segment intersection. return false; } // Check line segment B if ((long(X) < b1.GetValue()) || (b2.GetValue() < long(X))) { // The line intersection is not within segment B, no segment intersection. return false; } // Successfull segment intersection, calculate the Y value and return; M = ((Y2 - Y1) / (X2 - X1)); B = Y1 - (M * X1); // We must properly handle roundoff to FuzzyElement's value and still have a straight segment line. X = RoundNearest(X); Y = (M * X) + B; pPoint->SetValue(long(RoundNearest(X))); pPoint->SetMembership(Y); return true; }
int Round(double x, Rounding rounding) { switch (rounding) { case ROUND_UP : return RoundUp (x); case ROUND_DOWN: return RoundDown (x); default : return RoundNearest(x); } }