void Game::fillCircle(int cx, int cy, int radius, Color color) { struct Points { std::vector<SDL_Point> v; SDL_Point p; void add(int x, int y) { p.x = x; p.y = y; v.push_back(p); } SDL_Point* get() { return &v[0]; } int size() { return v.size(); } }; Points points; double r = static_cast<double>(radius); for (double dy = 1; dy < r; dy += 1.0) { double dx = floor(sqrt((2.0*r*dy) - (dy*dy))); int x = cx - dx; int y1 = cy + r - dy; int y2 = cy - r + dy; for (; x <= cx + dx; x++) { points.add(x, y1); points.add(x, y2); } } for (int x = cx - radius; x < cx + radius; x++) { points.add(x, cy); } SDL_SetRenderDrawColor(_renderer, color.r, color.g, color.b, color.a); SDL_RenderDrawPoints(_renderer, points.get(), points.size()); }
// TODO: Do horizontal sweep, when faster to do so // TODO: Preprocessor-conditional OpenGL alternative draw calls Points generate::triangle(SDL_Point a, SDL_Point b, SDL_Point c) { Points points; points.add(a); points.add(b); points.add(c); points.add(a); return points; }
void Game::drawCircle(int n_cx, int n_cy, int radius, Color color) { double error = static_cast<double>(-radius); double x = static_cast<double>(radius) -0.5; double y = static_cast<double>(0.5); double cx = static_cast<double>(n_cx) -0.5; double cy = static_cast<double>(n_cy) -0.5; struct Points { std::vector<SDL_Point> v; SDL_Point p; void add(int x, int y) { p.x = x; p.y = y; v.push_back(p); } SDL_Point* get() { return &v[0]; } int size() { return v.size(); } }; Points points; while (x >= y) { points.add(cx + x, cy + y); points.add(cx + y, cy + x); if (x != 0) { points.add(cx - x, cy + y); points.add(cx + y, cy - x); } if (y != 0) { points.add(cx + x, cy - y); points.add(cx - y, cy + x); } if (x != 0 && y != 0) { points.add(cx - x, cy - y); points.add(cx - y, cy - x); } error += y; ++y; error += y; if (error >= 0) { --x; error -= x; error -= x; } } SDL_SetRenderDrawColor(_renderer, color.r, color.g, color.b, color.a); SDL_RenderDrawPoints(_renderer, points.get(), points.size()); }
Points generate::polygon(int x, int y, float r, int sides, float offset) { using namespace math; Points points; points.points.reserve(sides+1); float angle_delta = two_pi/sides; SDL_Point point = {x,y}; for (float angle = fmod(offset, angle_delta); angle < two_pi; angle += angle_delta) { point.x = x + ((int) round(cos(angle)*r)); point.y = y + ((int) round(sin(angle)*r)); points.add(point); } points.add(points.points[0]); return points; }
Points generate::circle_filled(int x, int y, int r) { using namespace math; Points points; points.points.reserve((r+1)*4); float xdif; int rsqr = sqr(r), x1,x2; for (int i = 0; i <= r; i++) { xdif = sqrt((float) (rsqr - sqr(i))); x1 = x +((int) round(-xdif)); x2 = x +((int) round(xdif)) -1; // Top half of circle points.add(x1, y-i); points.add(x2, y-i); // Bottom half of circle points.add(x1, y+i-1); points.add(x2, y+i-1); } return points; }
// ##### add() ####################################################### void Solids::add(Element object, Color color) { assert (object != NULL); Points points; cerr << "Solids::add()" << endl; for (int i= 0; i < object->getBorderPointCount(); ++i) { cerr << "find "; ((*object)[i]).print(); cerr << endl; Iterator it= find((*object)[i], color); while (exist(it)) { cerr << "in exist"; points+= it.solidIt->points; objs.erase(it.solidIt); } } cerr << "add-points" << endl; points.add(object); Solid newSolid; newSolid.points= points; newSolid.color= color; objs.insert(objs.begin(), newSolid); cerr << "solid-add end" << endl; }
Points generate::triangle_filled(SDL_Point a, SDL_Point b, SDL_Point c) { using namespace math; Points points; if (a.y > b.y) std::swap(a, b); if (b.y > c.y) { std::swap(b, c); if (a.y > b.y) std::swap(a, b); } points.points.reserve((c.y-a.y)*2); // note << "Generating triangle" << endl; // note << "xs: " << a.x << ", " << b.x << ", " << c.x << endl; // note << "ys: " << a.y << ", " << b.y << ", " << c.y << endl; Line ab = Line(a, b), ac = Line(a, c), bc = Line(b, c); if (ab.horizontal() == false) { float ab_slope = ab.slope(), ac_slope = ac.slope(); float factor = 0.f; Point p(0,0); for (int y = a.y; y <= b.y; y++) { p.y = y; p.x = (int) ((factor/ab_slope) +a.x); points.points.push_back(p); p.x = (int) ((factor/ac_slope) +a.x); points.points.push_back(p); factor++; } } else { points.add(a.x, a.y); points.add(b.x, a.y); } if (bc.horizontal() == false) { float bc_slope = bc.slope(), ac_slope = ac.slope(); float factor_a = (float) (b.y-a.y), factor_b = 0.f; Point p(0,0); for (int y = b.y; y <= c.y; y++) { p.y = y; p.x = (int) ((factor_b/bc_slope) +b.x); points.points.push_back(p); p.x = (int) ((factor_a/ac_slope) +a.x); points.points.push_back(p); // points.add((int) ((factor_b/bc_slope) +b.x), y); // points.add((int) ((factor_a/ac_slope) +a.x), y); factor_a++; factor_b++; } } else { points.add(b.x, b.y); points.add(c.x, b.y); } return points; }