GRectangle GArc::getBounds() const { if (transformed) { return stanfordcpplib::getPlatform()->gobject_getBounds(this); } double rx = frameWidth / 2; double ry = frameHeight / 2; double cx = x + rx; double cy = y + ry; double startRadians = start * PI / 180; double sweepRadians = sweep * PI / 180; double p1x = cx + cos(startRadians) * rx; double p1y = cy - sin(startRadians) * ry; double p2x = cx + cos(startRadians + sweepRadians) * rx; double p2y = cy - sin(startRadians + sweepRadians) * ry; double xMin = std::min(p1x, p2x); double xMax = std::max(p1x, p2x); double yMin = std::min(p1y, p2y); double yMax = std::max(p1y, p2y); if (containsAngle(0)) xMax = cx + rx; if (containsAngle(90)) yMin = cy - ry; if (containsAngle(180)) xMin = cx - rx; if (containsAngle(270)) yMax = cy + ry; if (isFilled()) { xMin = std::min(xMin, cx); yMin = std::min(yMin, cy); xMax = std::max(xMax, cx); yMax = std::max(yMax, cy); } return GRectangle(xMin, yMin, xMax - xMin, yMax - yMin); }
static GRectangle getBoundsGArc(GArc arc) { double rx, ry, cx, cy, p1x, p1y, p2x, p2y, xMin, xMax, yMin, yMax; rx = arc->width / 2; ry = arc->height / 2; cx = arc->x + rx; cy = arc->y + ry; p1x = cx + cosDegrees(arc->u.arcRep.start) * rx; p1y = cy - sinDegrees(arc->u.arcRep.start) * ry; p2x = cx + cosDegrees(arc->u.arcRep.start + arc->u.arcRep.sweep) * rx; p2y = cy - sinDegrees(arc->u.arcRep.start + arc->u.arcRep.sweep) * ry; xMin = fmin(p1x, p2x); xMax = fmax(p1x, p2x); yMin = fmin(p1y, p2y); yMax = fmax(p1y, p2y); if (containsAngle(arc, 0)) xMax = cx + rx; if (containsAngle(arc, 90)) yMin = cy - ry; if (containsAngle(arc, 180)) xMin = cx - rx; if (containsAngle(arc, 270)) yMax = cy + ry; if (arc->filled) { xMin = fmin(xMin, cx); yMin = fmin(yMin, cy); xMax = fmax(xMax, cx); yMax = fmax(yMax, cy); } return createGRectangle(xMin, yMin, xMax - xMin, yMax - yMin); }
bool GArc::contains(double x, double y) const { if (transformed) return pp->contains(this, x, y); double rx = frameWidth / 2; double ry = frameHeight / 2; if (rx == 0 || ry == 0) return false; double dx = x - (this->x + rx); double dy = y - (this->y + ry); double r = (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry); if (fillFlag) { if (r > 1.0) return false; } else { double t = ARC_TOLERANCE / ((rx + ry) / 2); if (abs(1.0 - r) > t) return false; } return containsAngle(atan2(-dy, dx) * 180 / PI); }
static bool containsGArc(GArc arc, double x, double y) { double rx, ry, dx, dy, r, t; rx = arc->width / 2; ry = arc->height / 2; if (rx == 0 || ry == 0) return false; dx = x - (arc->x + rx); dy = y - (arc->y + ry); r = (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry); if (arc->filled) { if (r > 1.0) return false; } else { t = ARC_TOLERANCE / ((rx + ry) / 2); if (abs(1.0 - r) > t) return false; } return containsAngle(arc, atan2(-dy, dx) * 180 / PI); }
bool GArc::contains(double x, double y) const { if (transformed) { return stanfordcpplib::getPlatform()->gobject_contains(this, x, y); } double rx = frameWidth / 2; double ry = frameHeight / 2; if (floatingPointEqual(rx, 0) || floatingPointEqual(ry, 0)) { return false; } double dx = x - (this->x + rx); double dy = y - (this->y + ry); double r = (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry); if (fillFlag) { if (r > 1.0) return false; } else { double t = ARC_TOLERANCE / ((rx + ry) / 2); if (std::fabs(1.0 - r) > t) return false; } // JL BUGFIX: must scale by ry, rx. return containsAngle(atan2(-dy/ry, dx/rx) * 180 / PI); }
// JL moved computation for transformed case into front end here bool GArc::contains(double x, double y) const { if (transformed) { GPoint pt = matrix.preimage(x - this->x, y - this->y); x = this->x + pt.getX(); y = this->y + pt.getY(); } double rx = frameWidth / 2; double ry = frameHeight / 2; if (rx == 0 || ry == 0) return false; double dx = x - (this->x + rx); double dy = y - (this->y + ry); double r = (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry); if (fillFlag) { if (r > 1.0) return false; } else { double t = ARC_TOLERANCE / ((rx + ry) / 2); if (abs(1.0 - r) > t) return false; } // BUGFIX (JL): must scale by ry, rx. In the case where frameWidth != frameHeight, // the "angles" used in the Java back end are not true angles, but instead are scaled // so that the 45-degree ray passes through the corner of the bounding box. return containsAngle(atan2(-dy/ry, dx/rx) * 180 / PI); }