@Override
 public boolean equals(Object obj) {
   if (obj instanceof FGERoundRectangle) {
     FGERoundRectangle p = (FGERoundRectangle) obj;
     if (getIsFilled() != p.getIsFilled()) {
       return false;
     }
     return ((Math.abs(getX() - p.getX()) <= EPSILON)
         && (Math.abs(getY() - p.getY()) <= EPSILON)
         && (Math.abs(getWidth() - p.getWidth()) <= EPSILON)
         && (Math.abs(getHeight() - p.getHeight()) <= EPSILON)
         && (Math.abs(getArcWidth() - p.getArcWidth()) <= EPSILON)
         && (Math.abs(getArcHeight() - p.getArcHeight()) <= EPSILON));
   }
   return super.equals(obj);
 }
  private FGEArea computeRectangleIntersection(FGERoundRectangle rect) {
    Vector<FGEPoint> pts =
        new Vector<FGEPoint>() {
          @Override
          public synchronized boolean add(FGEPoint o) {
            if (!contains(o)) {
              return super.add(o);
            }
            return false;
          }
        };

    List<FGESegment> sl = rect.getFrameSegments();
    for (FGESegment seg : sl) {
      FGEArea a = intersect(seg);
      if (a instanceof FGEPoint) {
        pts.add((FGEPoint) a);
      } else if (a instanceof FGESegment) {
        pts.add(((FGESegment) a).getP1());
        pts.add(((FGESegment) a).getP2());
      } else if (a instanceof FGEUnionArea) {
        for (FGEArea a2 : ((FGEUnionArea) a).getObjects()) {
          if (a2 instanceof FGEPoint) {
            pts.add((FGEPoint) a2);
          }
          if (a2 instanceof FGESegment) {
            pts.add(((FGESegment) a2).getP1());
            pts.add(((FGESegment) a2).getP2());
          }
        }
      }
    }

    FGEPoint ne, nw, se, sw;
    ne = new FGEPoint(x + width, y);
    nw = new FGEPoint(x, y);
    se = new FGEPoint(x + width, y + height);
    sw = new FGEPoint(x, y + height);
    if (rect.containsPoint(ne)) {
      pts.add(ne);
    }
    if (rect.containsPoint(nw)) {
      pts.add(nw);
    }
    if (rect.containsPoint(se)) {
      pts.add(se);
    }
    if (rect.containsPoint(sw)) {
      pts.add(sw);
    }

    if (pts.size() == 0) {
      return new FGEEmptyArea();
    } else if (pts.size() == 2) {
      return new FGESegment(pts.firstElement(), pts.elementAt(1));
    } else if (pts.size() != 4) {
      logger.warning(
          "Strange situation here while computeRectangleIntersection between "
              + this
              + " and "
              + rect);
    }

    double minx = java.lang.Double.POSITIVE_INFINITY;
    double miny = java.lang.Double.POSITIVE_INFINITY;
    double maxx = java.lang.Double.NEGATIVE_INFINITY;
    double maxy = java.lang.Double.NEGATIVE_INFINITY;
    for (FGEPoint p : pts) {
      if (p.x < minx) {
        minx = p.x;
      }
      if (p.y < miny) {
        miny = p.y;
      }
      if (p.x > maxx) {
        maxx = p.x;
      }
      if (p.y > maxy) {
        maxy = p.y;
      }
    }
    return new FGERoundRectangle(
        minx, miny, maxx - minx, maxy - miny, arcwidth, archeight, Filling.FILLED);
  }