32 #define FONTSTASH_IMPLEMENTATION // Expands implementation 34 #pragma warning(disable: 4505) // do not warn about unused functions 37 #pragma GCC diagnostic push 38 #pragma GCC diagnostic ignored "-Wunused-function" 42 #define GLFONTSTASH_IMPLEMENTATION // Expands implementation 47 #define CIRCLE_RESOLUTION (double)10 // inverse in degrees 58 GLdouble* vertex_data[4],
59 GLfloat weight[4], GLdouble** dataOut) {
64 vertex = (GLdouble*)malloc(7 *
sizeof(GLdouble));
66 vertex[0] = coords[0];
67 vertex[1] = coords[1];
68 vertex[2] = coords[2];
82 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
84 for (PositionVector::const_iterator i = v.begin(); i != v.end(); i++) {
86 glVertex2d(p.
x(), p.
y());
90 glVertex2d(p.
x(), p.
y());
101 GLUtesselator* tobj = gluNewTess();
102 gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
103 gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &glBegin);
104 gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &glEnd);
105 gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &
combCallback);
106 gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
107 gluTessBeginPolygon(tobj, NULL);
108 gluTessBeginContour(tobj);
109 double* points =
new double[(v.size() + int(close)) * 3];
111 for (
int i = 0; i != (int)v.size(); ++i) {
112 points[3 * i] = v[i].x();
113 points[3 * i + 1] = v[i].y();
114 points[3 * i + 2] = 0;
115 gluTessVertex(tobj, points + 3 * i, points + 3 * i);
118 const int i = (int)v.size();
119 points[3 * i] = v[0].x();
120 points[3 * i + 1] = v[0].y();
121 points[3 * i + 2] = 0;
122 gluTessVertex(tobj, points + 3 * i, points + 3 * i);
124 gluTessEndContour(tobj);
125 gluTessEndPolygon(tobj);
133 double width,
double offset) {
135 glTranslated(beg.
x(), beg.
y(), 0);
136 glRotated(rot, 0, 0, 1);
138 glVertex2d(-width - offset, 0);
139 glVertex2d(-width - offset, -visLength);
140 glVertex2d(width - offset, -visLength);
141 glVertex2d(width - offset, 0);
149 double rot,
double visLength,
152 glTranslated((beg2.
x() + beg1.
x())*.5, (beg2.
y() + beg1.
y())*.5, 0);
153 glRotated(rot, 0, 0, 1);
155 glVertex2d(-width, 0);
156 glVertex2d(-width, -visLength);
157 glVertex2d(width, -visLength);
158 glVertex2d(width, 0);
166 double delta = angle2 - angle1;
167 while (delta > 180) {
170 while (delta < -180) {
179 const std::vector<double>& rots,
180 const std::vector<double>& lengths,
181 double width,
int cornerDetail,
double offset) {
183 int e = (int) geom.size() - 1;
184 for (
int i = 0; i < e; i++) {
185 drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
188 if (cornerDetail > 0) {
189 for (
int i = 1; i < e; i++) {
191 glTranslated(geom[i].x(), geom[i].y(), 0.1);
192 double angleBeg = -rots[i - 1];
193 double angleEnd = 180 - rots[i];
195 std::swap(angleBeg, angleEnd);
201 if (angleEnd - angleBeg > 360) {
204 if (angleEnd - angleBeg < -360) {
208 if (angleEnd > angleBeg) {
220 const std::vector<double>& rots,
221 const std::vector<double>& lengths,
222 const std::vector<RGBColor>& cols,
223 double width,
int cornerDetail,
double offset) {
224 int e = (int) geom.size() - 1;
225 for (
int i = 0; i < e; i++) {
227 drawBoxLine(geom[i], rots[i], lengths[i], width, offset);
229 if (cornerDetail > 0) {
230 for (
int i = 1; i < e; i++) {
233 glTranslated(geom[i].x(), geom[i].y(), 0);
245 const std::vector<double>& rots,
246 const std::vector<double>& lengths,
248 int minS = (int)
MIN4(rots.size(), lengths.size(), geom1.size(), geom2.size());
249 for (
int i = 0; i < minS; i++) {
257 int e = (int) geom.size() - 1;
258 for (
int i = 0; i < e; i++) {
272 glTranslated(beg.
x(), beg.
y(), 0);
273 glRotated(rot, 0, 0, 1);
276 glVertex2d(0, -visLength);
284 double rot,
double visLength) {
286 glTranslated((beg2.
x() + beg1.
x())*.5, (beg2.
y() + beg1.
y())*.5, 0);
287 glRotated(rot, 0, 0, 1);
290 glVertex2d(0, -visLength);
300 int e = (int) v.size() - 1;
301 for (
int i = 0; i < e; ++i) {
302 glVertex2d(v[i].x(), v[i].y());
303 glVertex2d(v[i + 1].x(), v[i + 1].y());
312 int e = (int) v.size() - 1;
313 for (
int i = 0; i < e; ++i) {
315 glVertex2d(v[i].x(), v[i].y());
316 glVertex2d(v[i + 1].x(), v[i + 1].y());
325 glVertex2d(beg.
x(), beg.
y());
326 glVertex2d(end.
x(), end.
y());
349 std::vector<Position>
352 std::vector<Position> result;
353 const double inc = 360 / (double)steps;
355 for (
int i = 0; i <= steps; ++i) {
357 result.push_back(
Position(vertex.first * width, vertex.second * width));
372 const double inc = (end - beg) / (
double)steps;
373 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
376 for (
int i = 0; i <= steps; ++i) {
378 glBegin(GL_TRIANGLES);
379 glVertex2d(p1.first * width, p1.second * width);
380 glVertex2d(p2.first * width, p2.second * width);
396 double beg,
double end) {
398 for (
int i = 0; i < 360; i += 10) {
399 double x = (double) sin(
DEG2RAD(i));
400 double y = (double) cos(
DEG2RAD(i));
404 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
405 std::pair<double, double> p1 =
407 for (
int i = (
int)(beg / 10); i < steps && (36.0 / (double) steps * (
double) i) * 10 < end; i++) {
408 const std::pair<double, double>& p2 =
410 glBegin(GL_TRIANGLES);
411 glVertex2d(p1.first * width, p1.second * width);
412 glVertex2d(p2.first * width, p2.second * width);
413 glVertex2d(p2.first * iwidth, p2.second * iwidth);
415 glVertex2d(p2.first * iwidth, p2.second * iwidth);
416 glVertex2d(p1.first * iwidth, p1.second * iwidth);
417 glVertex2d(p1.first * width, p1.second * width);
421 const std::pair<double, double>& p2 =
423 glBegin(GL_TRIANGLES);
424 glVertex2d(p1.first * width, p1.second * width);
425 glVertex2d(p2.first * width, p2.second * width);
426 glVertex2d(p2.first * iwidth, p2.second * iwidth);
428 glVertex2d(p2.first * iwidth, p2.second * iwidth);
429 glVertex2d(p1.first * iwidth, p1.second * iwidth);
430 glVertex2d(p1.first * width, p1.second * width);
437 double tLength,
double tWidth) {
439 if (length < tLength) {
440 tWidth *= length / tLength;
445 glTranslated(rl.
x(), rl.
y(), 0);
447 glBegin(GL_TRIANGLES);
448 glVertex2d(0, tLength);
449 glVertex2d(-tWidth, 0);
450 glVertex2d(+tWidth, 0);
456 const std::vector<RGBColor>&
480 contourback = contourback.
reverse();
481 for (
auto i : contourback) {
482 contourFront.push_back(i);
484 contourFront.push_back(shape.front());
489 glTranslated(0, 0, type + 2);
506 glTranslated(0, 0, type + 0.1);
523 contourFront.
move2side(offsetFrontShape);
525 contourback = contourback.
reverse();
526 for (
auto i : contourback) {
527 contourFront.push_back(i);
529 contourFront.push_back(frontShape.front());
533 glTranslated(0, 0, type + 2);
549 shape.push_back(
Position(width / 2, height / 2));
550 shape.push_back(
Position(width / -2, height / 2));
551 shape.push_back(
Position(width / -2, height / -2));
552 shape.push_back(
Position(width / 2, height / -2));
553 shape.push_back(
Position(width / 2, height / 2));
557 glTranslated(center.
x(), center.
y(), type + 2);
561 glRotated(rotation, 0, 0, 1);
563 glTranslated(offsetX, offsetY, 0);
581 glGetDoublev(GL_CURRENT_COLOR, current);
582 return RGBColor(static_cast<unsigned char>(current[0] * 255. + 0.5),
583 static_cast<unsigned char>(current[1] * 255. + 0.5),
584 static_cast<unsigned char>(current[2] * 255. + 0.5),
585 static_cast<unsigned char>(current[3] * 255. + 0.5));
612 const double layer,
const double size,
613 const RGBColor& col,
const double angle,
const int align,
622 glAlphaFunc(GL_GREATER, 0.5);
623 glEnable(GL_ALPHA_TEST);
624 glTranslated(pos.
x(), pos.
y(), layer);
626 glRotated(-angle, 0, 0, 1);
636 const double layer,
const double size,
638 const double angle) {
642 double boxAngle = angle + 90;
643 if (boxAngle > 360) {
647 const double borderWidth = size / 20;
648 const double boxHeight = size * 0.8;
649 const double boxWidth = stringWidth + size / 2;
651 glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
652 glTranslated(0, 0, layer);
655 left.
sub(boxWidth / 2, 0);
657 left.
add(borderWidth * 1.5, 0);
659 glTranslated(0, 0, 0.01);
660 drawBoxLine(left, boxAngle, boxWidth - 3 * borderWidth, boxHeight - 2 * borderWidth);
662 drawText(text, pos, layer + 0.02, size, txtColor, angle);
671 const double rot =
RAD2DEG(atan2((end.
x() - f.
x()), (f.
y() - end.
y())));
672 glTranslated(end.
x(), end.
y(), 0);
673 glRotated(rot, 0, 0, 1);
681 const std::vector<double>& rots,
682 const std::vector<double>& lengths,
683 double length,
double spacing,
684 double halfWidth,
bool drawForSelecting) {
687 glTranslated(0, 0, 0.1);
688 int e = (int) geom.size() - 1;
689 for (
int i = 0; i < e; ++i) {
691 glTranslated(geom[i].x(), geom[i].y(), 0.0);
692 glRotated(rots[i], 0, 0, 1);
694 if (!drawForSelecting) {
695 for (
double t = 0; t < lengths[i]; t += spacing) {
697 glVertex2d(-halfWidth, -t);
698 glVertex2d(-halfWidth, -t - length);
699 glVertex2d(halfWidth, -t - length);
700 glVertex2d(halfWidth, -t);
706 glVertex2d(-halfWidth, 0);
707 glVertex2d(-halfWidth, -lengths.back());
708 glVertex2d(halfWidth, -lengths.back());
709 glVertex2d(halfWidth, 0);
722 for (
int i = 0; i < (int)shape.size(); ++i) {
FONS_DEF void fonsSetAlign(FONScontext *s, int align)
static std::vector< std::pair< double, double > > myCircleCoords
Storage for precomputed sin/cos-values describing a circle.
static void resetFont()
to be called when the font context is invalidated
FONS_DEF float fonsDrawText(FONScontext *s, float x, float y, const char *string, const char *end)
static void drawBoxLines(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double width, int cornerDetail=0, double offset=0)
Draws thick lines.
void add(const Position &pos)
Adds the given position to this one.
static void drawTextAtEnd(const std::string &text, const PositionVector &shape, double x, double size, RGBColor color)
draw text and the end of shape
static RGBColor fromHSV(double h, double s, double v)
Converts the given hsv-triplet to rgb.
static const RGBColor WHITE
static bool initFont()
init myFont
unsigned char alpha() const
Returns the alpha-amount of the color.
T MIN4(T a, T b, T c, T d)
PositionVector resample(double maxLength) const
resample shape with the given number of points (equal spacing)
static void debugVertices(const PositionVector &shape, double size, double layer=256)
draw vertex numbers for the given shape (in a random color)
double y() const
Returns the y-position.
static double rand(std::mt19937 *rng=0)
Returns a random real number in [0, 1)
double x() const
Returns the x-position.
static void drawText(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &col=RGBColor::BLACK, const double angle=0, int align=0, double width=-1)
void glfonsDelete(FONScontext *ctx)
FONS_DEF void fonsSetFont(FONScontext *s, int font)
double angleTo2D(const Position &other) const
returns the angle in the plane of the vector pointing from here to the other position ...
unsigned int glfonsRGBA(unsigned char r, unsigned char g, unsigned char b, unsigned char a)
static void drawFilledPoly(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
PositionVector reverse() const
reverse position vector
unsigned char blue() const
Returns the blue-amount of the color.
static const RGBColor BLACK
static void drawFilledCircle(double width, int steps=8)
Draws a filled circle around (0,0)
#define UNUSED_PARAMETER(x)
static void drawFilledPolyTesselated(const PositionVector &v, bool close)
Draws a filled polygon described by the list of points.
static double naviDegree(const double angle)
std::string toString(const T &t, std::streamsize accuracy=gPrecision)
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
A point in 2D or 3D with translation and scaling methods.
static std::vector< Position > drawFilledCircleReturnVertices(double width, int steps=8)
Draws a filled circle around (0,0) returning circle vertex.
static int angleLookup(double angleDeg)
normalize angle for lookup in myCircleCoords
static void drawOutlineCircle(double width, double iwidth, int steps=8)
Draws an unfilled circle around (0,0)
static void drawLine(const Position &beg, double rot, double visLength)
Draws a thin line.
void move2side(double amount)
move position vector to side using certain ammount
static struct FONScontext * myFont
Font context.
FONS_DEF void fonsSetColor(FONScontext *s, unsigned int color)
static void drawTextBox(const std::string &text, const Position &pos, const double layer, const double size, const RGBColor &txtColor=RGBColor::BLACK, const RGBColor &bgColor=RGBColor::WHITE, const RGBColor &borderColor=RGBColor::BLACK, const double angle=0)
draw Text box with given parameters
void APIENTRY combCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
FONS_DEF void fonsSetSize(FONScontext *s, float size)
static void drawShapeDottedContour(const int type, const PositionVector &shape, const double width)
draw a dotted contour around the given Non closed shape with certain width
unsigned char green() const
Returns the green-amount of the color.
unsigned char data_font_Roboto_Medium_ttf[]
static void drawCrossTies(const PositionVector &geom, const std::vector< double > &rots, const std::vector< double > &lengths, double length, double spacing, double halfWidth, bool drawForSelecting)
draw crossties for railroads or pedestrian crossings
static bool rightTurn(double angle1, double angle2)
whether the road makes a right turn (or goes straight)
static std::vector< RGBColor > myDottedcontourColors
static vector with a list of alternated black/white colors (used for contourns)
#define CIRCLE_RESOLUTION
unsigned int data_font_Roboto_Medium_ttf_len
unsigned char red() const
Returns the red-amount of the color.
FONScontext * glfonsCreate(int width, int height, int flags)
static void drawTriangleAtEnd(const Position &p1, const Position &p2, double tLength, double tWidth)
Draws a triangle at the end of the given line.
double distanceTo(const Position &p2) const
returns the euclidean distance in 3 dimension
FONS_DEF int fonsAddFontMem(FONScontext *s, const char *name, unsigned char *data, int ndata, int freeData)
struct FONScontext FONScontext
static void drawBoxLine(const Position &beg, double rot, double visLength, double width, double offset=0)
Draws a thick line.
Position positionAtOffset(double pos, double lateralOffset=0) const
Returns the position at the given length.
FONS_DEF float fonsTextBounds(FONScontext *s, float x, float y, const char *string, const char *end, float *bounds)
static const std::vector< RGBColor > & getDottedcontourColors(const int size)
get dotted contour colors (black and white). Vector will be automatically increased if current size i...
static RGBColor getColor()
gets the gl-color
void sub(double dx, double dy)
Substracts the given position from this one.