#include "GLDraw.h" namespace Upp { void Ellipse(GLTriangles& tr, Pointf center, Sizef radius, Color color, double width, Color line_color, double alpha) { static Pointf e[256]; static byte step[65]; ONCELOCK { for(int i = 0; i < 256; i++) e[i] = Polar(i * M_2PI / 256.0); for(int i = 0; i < 65; i++) { int h = 2 * i; int s = 4; while(s < h) s += s; step[i] = 256 / min(s, 256); } } double rmin = min(radius.cx, radius.cy); if(rmin <= 1e-100) return; int st = (int)max(radius.cx, radius.cy); st = st < 65 ? step[st] : 1; if(width >= rmin) { width = 0; color = line_color; } bool circle = radius.cx == radius.cy; if(width >= 0 && circle) width = width / radius.cx; int c = tr.Vertex(center, color, alpha); int a, a0; int la, lao, la0, lao0; bool has_line = width > 0 && !IsNull(line_color); bool has_interior = !IsNull(color); for(int i = 0; i < 256; i += st) { Pointf dir = radius * e[i]; int b, lb, lbo; if(has_line) { // we need to draw border line lbo = tr.Vertex(center + dir, line_color, alpha); // outer point dir -= circle ? width * dir : width * Normalize(dir); lb = tr.Vertex(center + dir, line_color, alpha); // inner point } b = tr.Vertex(center + dir, color, alpha); if(i) { if(has_line) { tr.Triangle(la, lao, lbo); tr.Triangle(lbo, lb, la); } if(has_interior) tr.Triangle(c, a, b); } else { a0 = b; la0 = lb; lao0 = lbo; } a = b; la = lb; lao = lbo; } if(has_interior) tr.Triangle(c, a, a0); if(has_line) { tr.Triangle(la, lao, lao0); tr.Triangle(lao0, la0, la); } } };