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;        
}
示例#2
0
int Round(double x, Rounding rounding) {
  switch (rounding) {
    case ROUND_UP  : return RoundUp     (x);
    case ROUND_DOWN: return RoundDown   (x);
    default        : return RoundNearest(x);
  }
}