/* * Function: horizontallyDisplacedPoint * Usage: points.insert(2*i+1, horizontallyDisplacedPoint(points[2*i], points[2*i+1], order)); * -------------------------- * Like randomClosePoint, but only displaced the point in the x direction. */ GPoint horizontallyDisplacedPoint(GPoint a, GPoint b, int order, double deformation){ double xAve = (a.getX()+b.getX())/2; double yAve = (a.getY()+b.getY())/2; double deform = deformation/exp(LIGHTNING_ORDER-order); double x = randomReal((1-deform)*xAve, (1+deform)*xAve); return GPoint(x,yAve); }
/* * Function: verticallyDisplacedPoint * Usage: points.insert(2*i+1, verticallyDisplacedPoint(points[2*i], points[2*i+1], order)); * -------------------------- * Like randomClosePoint, but only displaced the point in the y direction. */ GPoint verticallyDisplacedPoint(GPoint a, GPoint b, int order){ double xAve = (a.getX()+b.getX())/2; double yAve = (a.getY()+b.getY())/2; double deform = BACK_MOUNTAIN_DEFORMATION/exp(BACK_MOUNTAIN_ORDER-order); double y = randomReal((1-deform)*yAve, (1+deform)*yAve); return GPoint(xAve,y); }
GLine::GLine(const GPoint& p0, const GPoint& p1) { stanfordcpplib::getPlatform()->gline_constructor( this, p0.getX(), p0.getY(), p1.getX(), p1.getY()); x = p0.getX(); y = p0.getY(); dx = p1.getX() - p0.getX(); dy = p1.getY() - p1.getY(); }
GPoint adjacentGPoint(GPoint start, Direction dir) { switch (dir) { case NORTH: return GPoint(start.getX(), start.getY() - 1); case EAST: return GPoint(start.getX() + 1, start.getY()); case SOUTH: return GPoint(start.getX(), start.getY() + 1); case WEST: return GPoint(start.getX() - 1, start.getY()); } return start; }
void drawPathfinderNode(GPoint center, string color, string label) { setColor(color); fillCircle(center.getX(), center.getY(), NODE_RADIUS); if (!label.empty()) { setFont(LABEL_FONT); drawString(label, center.getX() + NODE_RADIUS + 2, center.getY() + 5); } }
/* * Function: drawBranch * Usage: drawBranch(gw, branchStart, GPoint(width*(xMult-.15), height*(yMult-.15)), BRANCH_THICKNESS); * -------------------------- * Draws branches that continue and branch of probabilistically. */ void drawBranch(GWindow gw, GPoint start, GPoint finish, double width){ GPolygon *branch = branchPolygon(start, finish, width); branch->setFilled(true); branch->setColor(4270639); gw.add(branch); Vector<GPoint> points = branch->getVertices(); start = points[points.size()/4]; double endX = randomReal(start.getX()*(1-TREE_DEFORMATION), start.getX()*(1+TREE_DEFORMATION)); double endY = randomReal(1+TREE_DEFORMATION, 1+2*TREE_DEFORMATION)*(finish.getY()-start.getY())+start.getY(); if((endY-finish.getY())<-3){ drawBranch(gw, start,GPoint(endX, endY),width/2); } }
/* * Function: drawTrunk * Usage: drawTrunk(gw, branchStart);; * -------------------------- * Draws a curvy looking trunk structure on the GWindow. */ void drawTrunk(GWindow gw, GPoint start){ GPoint finish = GPoint(start.getX(), height); GPolygon * trunk = trunkPolygon(start, finish, BRANCH_THICKNESS); trunk->setFilled(true); trunk->setColor(4270639); gw.add(trunk); }
// JL added code to handle transformed case bool GPolygon::contains(double x, double y) const { int crossings = 0; int n = vertices.size(); if (n < 2) return false; if (vertices[0] == vertices[n - 1]) n--; x = x - getX(); // BUGFIX (JL) - must translate by anchor point y = y - getY(); double x0 = vertices[0].getX(); double y0 = vertices[0].getY(); for (int i = 1; i <= n; i++) { double x1 = vertices[i % n].getX(); double y1 = vertices[i % n].getY(); if (transformed) { GPoint pt = matrix.image(x1, y1); x1 = pt.getX(); y1 = pt.getY(); } if ((y0 > y) != (y1 > y) && x - x0 < (x1 - x0) * (y - y0) / (y1 - y0)) { crossings++; } x0 = x1; y0 = y1; } return (crossings % 2 == 1); }
// added by JL bool GImage::contains(double x, double y) const { GPoint p = matrix.preimage(x - this->x, y - this->y); double xx = p.getX(); double yy = p.getY(); return 0 < xx && xx <= width && 0 < yy && yy <= height; }
/* * Function: randomClosePoint * Usage: GPoint A = randomClosePoint(triangle[0], triangle[1], order); * -------------------------- * Given two points, this algorithm finds a point near their midpoint, but displaced by a random amount. */ GPoint randomClosePoint(GPoint a, GPoint b, int order){ /* With the folded triangle algorithm, you want to return the same randomClosePoint every time. * This is basically a checksum so that the algorithm does so, but can maintain a high degree of randomness, * which setting the same random seed over and over again won't do. */ double key = a.getX()+a.getY()+b.getX()+b.getY(); if(closePoints.containsKey(key)){ return closePoints[key]; } double xAve = (a.getX()+b.getX())/2; double yAve = (a.getY()+b.getY())/2; double deform = TERRAIN_DEFORMATION/exp(TERRAIN_ORDER-order); double x = randomReal((1-deform)*xAve, (1+deform)*xAve); double y = randomReal((1-deform)*yAve, (1+deform)*yAve); closePoints.put(key, GPoint(x,y)); return GPoint(x, y); }
void drawTriangle_by_center(const GPoint& center, const double& len) { double center_x = center.getX(); double center_y = center.getY(); GPoint a(center_x-len/2, center_y-SQRT3/6*len); GPoint b(center_x+len/2, center_y-SQRT3/6*len); GPoint c(center_x, center_y+SQRT3/3*len); drawTriangle(a, b, c); }
/* Construct a new IComboBox from the passed in values. * constructor does not do any parameter checking at this time. * * PARAMS * location - the top left corner of the box * size - the size in the X, Y and Z directions * paneColor - the color of the pane */ IComboBox::IComboBox(GPoint location, GPoint size, GColor paneColor, int itemNumber) { this->location = location; this->size = size; this->paneColor = paneColor; line_max = itemNumber; if (line_max < 5) line_max = 5; //this->size.setY(line_max * 4); if (CHAR_CNT(size.getX()) < 5) { this->size.setX(5 * CHAR_WIDTH + OVERHEAD); } char_max = CHAR_CNT(this->size.getX()); item_cnt = 0; head = NULL; top = head; next_idx = 0; Text = (char*)malloc(sizeof (char) * 2 + 1); Text = ""; TextLongName = (char*)malloc(sizeof(char) * 2 + 1); TextLongName = ""; //Set ListBox drawing variables ListBoxLocation = GPoint(location.getX(), location.getY() - size.getY() - 0.5, location.getZ()); ListBoxSize = GPoint(size.getX() - 0.5, itemNumber * 4, size.getZ()); //Set external flags to default CloseList = false; OpenList = false; TitleChange = false; FocusLock = false; //Set animation flags Animate = true; aa = 0.0; dohighlight = false; highlight = 0; //Set reading flags ReRead = false; Items = NULL; }
// JL added bool GLabel::contains(double x, double y) const { x -= this->x; y -= this->y; if (transformed) { GPoint pt = matrix.preimage(x, y); x = pt.getX(); y = pt.getY(); } return 0 <= x && x <= width && -ascent <= y && y <= -ascent + height; }
bool GOval::contains(double x, double y) const { GPoint p = matrix.preimage(x - this->x, y - this->y); double xx = p.getX(); double yy = p.getY(); double rx = width / 2; double ry = height / 2; if (rx == 0 || ry == 0) return false; double dx = xx - rx; double dy = yy - ry; return (dx * dx) / (rx * rx) + (dy * dy) / (ry * ry) <= 1.0; }
/* * Function: drawLightning * Usage: if(lightning->isSelected()) drawLightning(gw, GPoint(width*randomReal(.2, .8), 0), GPoint(width*randomReal(.2, .8), height)); * -------------------------- * Adds a lightning shaped polygon to the screen that branches off probabilistically. */ void drawLightning(GWindow gw, GPoint start, GPoint end){ GPolygon *lightning = lightningPolygon(start, end); lightning->setFilled(true); lightning->setColor(LIGHTNING_OUTER_COLOR); lightning->setFillColor(LIGHTNING_INNER_COLOR); gw.add(lightning); if(randomChance(.7)){ Vector<GPoint> points = lightning->getVertices(); start = points[points.size()/4]; drawLightning(gw, start,GPoint(start.getX(), height)); } }
// JL rewrote to include transformed case in front end GRectangle GLine::getBounds() const { double tdx = dx; double tdy = dy; if (transformed) { GPoint pt = matrix.image(dx, dy); tdx = pt.getX(); tdy = pt.getY(); } double x0 = (tdx < 0) ? x + tdx : x; double y0 = (tdy < 0) ? y + tdy : y; return GRectangle(x0, y0, abs(tdx), abs(tdy)); }
// JL rewrote to handle transformed case bool GCompound::contains(double x, double y) const { x -= this->x; y -= this->y; if (transformed) { GPoint pt = matrix.preimage(x, y); x = pt.getX(); y = pt.getY(); } for (int i = 0; i < contents.size(); i++) { if (contents.get(i)->contains(x, y)) return true; } return false; }
void drawTree(double x, double y, double r, double theta, int depth) { if (depth < MAX_DEPTH) { double growth = randomReal(0.1, 0.4); setColor(TREE_COLORS[depth]); GPoint branchPt = drawPolarLine(x, y, r * growth, theta); int numChildren = randomInteger(2, 8); for (int i = 0; i < numChildren; i++) { double thetaPrime = theta + randomReal(-45, +45); drawTree(branchPt.getX(), branchPt.getY(), (1.0 - growth) * r, thetaPrime, depth + 1); } } }
void drawSierpinski(const GPoint& center, const double& len, const int& order) { drawTriangle_by_center(center, len); int new_order = order-1; if (new_order > 0) { double center_x = center.getX(); double center_y = center.getY(); GPoint center_a(center_x-len/2, center_y+SQRT3/6*len); GPoint center_b(center_x+len/2, center_y+SQRT3/6*len); GPoint center_c(center_x, center_y-SQRT3/3*len); drawSierpinski(center_a, len/2, new_order); drawSierpinski(center_b, len/2, new_order); drawSierpinski(center_c, len/2, new_order); } }
void drawSierpinkiTriangle(GPoint & top,int edge,int order,GWindow & gw) { int triangleHeight = (int)sqrt(pow((double)edge,2) - pow((double)edge/2,2)); GPoint ptA = top; GPoint ptB((top.getX() - (triangleHeight/2)),(top.getY()+triangleHeight)); GPoint ptC((top.getX() + (triangleHeight/2)),(top.getY()+triangleHeight)); gw.drawLine(ptA,ptB); gw.drawLine(ptB,ptC); gw.drawLine(ptC,ptA); if(order != 0) { order -= 1; edge = edge / 2; if(edge != 0) { triangleHeight = triangleHeight / 2; GPoint ptAb = top; GPoint ptBb((top.getX()-(triangleHeight/2)),(top.getY()+triangleHeight)); GPoint ptCb((top.getX() + (triangleHeight / 2)), (top.getY() + triangleHeight)); drawSierpinkiTriangle(ptAb, edge, order, gw); drawSierpinkiTriangle(ptBb, edge, order, gw); drawSierpinkiTriangle(ptCb, edge, order, gw); } } }
// Rewritten by JL to handle transformed case and take corners into account bool GRoundRect::contains(double x, double y) const { GPoint p = matrix.preimage(x - this->x, y - this->y); double xx = p.getX(); double yy = p.getY(); if (xx < 0 || xx > width || yy < 0 || yy > height) return false; // If corner diameter is too big, the largest sensible value is used by Java back end. double a = std::min(corner, width) / 2; double b = std::min(corner, height) / 2; // Get distances from nearest edges of bounding rectangle double dx = std::min(xx, width - xx); double dy = std::min(yy, height - yy); if (dx > a || dy > b) return true; // in "central cross" of rounded rect return (dx - a)*(dx - a)/(a*a) + (dy - b)*(dy - b)/(b*b) <= 1; }
// JL rewrote to include transformed case in front end bool GLine::contains(double x, double y) const { double x0 = getX(); double y0 = getY(); double x1 = x0 + dx; double y1 = y0 + dy; if (transformed) { GPoint pt = matrix.image(dx, dy); x1 = x0 + pt.getX(); y1 = y0 + pt.getY(); } double tSquared = LINE_TOLERANCE * LINE_TOLERANCE; if (dsq(x, y, x0, y0) < tSquared) return true; if (dsq(x, y, x1, y1) < tSquared) return true; if (x < min(x0, x1) - LINE_TOLERANCE) return false; if (x > max(x0, x1) + LINE_TOLERANCE) return false; if (y < min(y0, y1) - LINE_TOLERANCE) return false; if (y > max(y0, y1) + LINE_TOLERANCE) return false; if ((float) (x0 - x1) == 0 && (float) (y0 - y1) == 0) return false; double u = ((x - x0) * (x1 - x0) + (y - y0) * (y1 - y0)) / dsq(x0, y0, x1, y1); return dsq(x, y, x0 + u * (x1 - x0), y0 + u * (y1 - y0)) < tSquared; }
// JL added code to handle transformed case GRectangle GPolygon::getBounds() const { double xMin = 0; double yMin = 0; double xMax = 0; double yMax = 0; double x0 = getX(); double y0 = getY(); for (int i = 0; i < vertices.size(); i++) { double x = vertices[i].getX(); double y = vertices[i].getY(); if (transformed) { GPoint pt = matrix.image(x, y); x = pt.getX(); y = pt.getY(); } if (i == 0 || x < xMin) xMin = x; if (i == 0 || y < yMin) yMin = y; if (i == 0 || x > xMax) xMax = x; if (i == 0 || y > yMax) yMax = y; } return GRectangle(xMin + x0, yMin + y0, xMax - xMin, yMax - yMin); // BUGFIX (JL): Must translate by x0, y0. }
// This is the core function to solve queen problem // queen_to_find is the number of queens to be find. bool solve(Grid<bool> &ChessBoard, GPoint start, int queen_to_find) { if(queen_to_find == 0) return true; int i,j; int board_size = ChessBoard.numRows(); int start_x = start.getX(); int start_y = start.getY(); ChessBoard.set(start_x, start_y, true); display_ChessBoard(ChessBoard); Direction dirs[4] = {NORTH, EAST,SOUTH, WEST}; for(int i = 0; i < 4; i++) { GPoint adjPoint = adjacentGPoint(start, dirs[i]); if(!can_be_placed(ChessBoard, adjPoint)) continue; if(solve(ChessBoard, adjPoint, queen_to_find - 1 )) return true; } ChessBoard.set(start_x, start_y, false); return false; }
// 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); }
bool GObject::contains(const GPoint& pt) const { return contains(pt.getX(), pt.getY()); }
void GObject::setLocation(const GPoint& pt) { setLocation(pt.getX(), pt.getY()); }
bool GRectangle::contains(GPoint pt) const { return contains(pt.getX(), pt.getY()); }
double vectorAngle(const GPoint & pt) { return vectorAngle(pt.getX(), pt.getY()); }
double vectorDistance(const GPoint & pt) { return vectorDistance(pt.getX(), pt.getY()); }