Skip to main content
  • Home
  • Development
  • Documentation
  • Donate
  • Operational login
  • Browse the archive

swh logo
SoftwareHeritage
Software
Heritage
Archive
Features
  • Search

  • Downloads

  • Save code now

  • Add forge now

  • Help

swh:1:snp:818279ffd0c3c25a68d33cc2b97d007e1bdc7ed6
  • Code
  • Branches (2)
  • Releases (0)
    • Branches
    • Releases
    • HEAD
    • refs/heads/master
    • refs/import/raw
    No releases to show
  • adfc2e5
  • /
  • CustomDrawObjects.h
Raw File Download
Permalinks

To reference or cite the objects present in the Software Heritage archive, permalinks based on SoftWare Hash IDentifiers (SWHIDs) must be used.
Select below a type of object currently browsed in order to display its associated SWHID and permalink.

  • content
  • directory
  • revision
  • snapshot
content badge Iframe embedding
swh:1:cnt:1db466506e9ea6d36ac487fdd2777fa06a394a98
directory badge Iframe embedding
swh:1:dir:adfc2e5cc8c77574bf911dbe899dca63ac7d8564
revision badge
swh:1:rev:39b13612ebd645a65eda854771b517371f2f858a
snapshot badge
swh:1:snp:818279ffd0c3c25a68d33cc2b97d007e1bdc7ed6
Citations

This interface enables to generate software citations, provided that the root directory of browsed objects contains a citation.cff or codemeta.json file.
Select below a type of object currently browsed in order to generate citations for them.

  • content
  • directory
  • revision
  • snapshot
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Generate software citation in BibTex format (requires biblatex-software package)
Generating citation ...
Tip revision: 39b13612ebd645a65eda854771b517371f2f858a authored by ennetws on 13 March 2015, 18:17:18 UTC
Create README.md
Tip revision: 39b1361
CustomDrawObjects.h
#pragma once

#include <float.h>
#include <qgl.h>
#include <QVector3D>
#include "RenderObject.h"

#include "SurfaceMeshModel.h"
using namespace SurfaceMesh;
using namespace Eigen;

#define glVertQt(v) glVertex3d(v.x(), v.y(), v.z())
#define glColorQt(c) glColor4d(c.redF(), c.greenF(), c.blueF(), c.alphaF())
#define glv(v) glVertex3dv(v.data())

#ifndef GL_MULTISAMPLE
#define GL_MULTISAMPLE  0x809D
#endif

// Custom QVector3D
class QVector3: public QVector3D{
public:
	QVector3(){ setX(0);setY(0);setZ(0); }
	QVector3(double x, double y, double z){ this->setX(x);this->setY(y);this->setZ(z); }
	QVector3 (const QVector3D& v){ this->setX(v.x());this->setY(v.y());this->setZ(v.z()); }
	QVector3 (const Vector3d& v){ this->setX(v.x());this->setY(v.y());this->setZ(v.z()); }
	operator const Vector3d() { return Vector3d(x(),y(),z()); }
	operator const QVector3D() { return *this; }
};

class PolygonSoup : public RenderObject::Base{
	QVector< QVector<QVector3> > polys;
	QVector< QVector3 > polys_normals;
	QVector< QColor > polys_colors;

public:
	PolygonSoup():RenderObject::Base(1, Qt::black){}

	void clear(){
		polys.clear();
		polys_normals.clear();
		polys_colors.clear();
	}

    void draw(QGLWidget &widget){ this->draw(); Q_UNUSED(widget) }

	void draw(){

        glEnable(GL_LIGHTING);
		glEnable(GL_BLEND);

        drawTris();
        drawQuads();

        glDisable(GL_LIGHTING);

		// Draw borders as lines and points to force drawing something
		glLineWidth(2.0f);
		glColor4d(0,0,0,1);
		glBegin(GL_LINES);
		foreach(QVector<QVector3> poly, polys){
			for(int i = 0; i < (int) poly.size(); i++){
				glVertQt(poly[i]);
				glVertQt(poly[(i+1) % poly.size()]);
			}
		}
		glEnd();

		glPointSize(3.0f);
		glBegin(GL_POINTS);
		foreach(QVector<QVector3> poly, polys){
			for(int i = 0; i < (int) poly.size(); i++)
				glVertQt(poly[i]);
		}
		glEnd();
		glEnable(GL_LIGHTING);
	}

	void drawTris(bool isColored = true){
		glBegin(GL_TRIANGLES);
		for(int i = 0; i < (int) polys.size(); i++)
		{
			if(polys[i].size() != 3) continue;
			else{
				glNormal3d(polys_normals[i].x(),polys_normals[i].y(),polys_normals[i].z());
				if(isColored) glColorQt(polys_colors[i]);
				for(int p = 0; p < 3; p++) glVertQt(polys[i][p]);
			}
		}
		glEnd();
	}

	void drawQuads(bool isColored = true){
		glBegin(GL_QUADS);
		for(int i = 0; i < (int) polys.size(); i++)
		{
			if(polys[i].size() != 4) continue;
			else{
				glNormal3d(polys_normals[i].x(),polys_normals[i].y(),polys_normals[i].z());
				if(isColored) glColorQt(polys_colors[i]);
				for(int p = 0; p < 4; p++) glVertQt(polys[i][p]);
			}
		}
		glEnd();
	}

	void addPoly(const QVector<QVector3>& points, const QColor& c = Qt::red){
		if(points.size() < 3) return;
		else
			polys.push_back(points);

		// Compute normal from 3 points
		polys_normals.push_back(QVector3D::crossProduct(points[1] - points[0], points[2] - points[0]).normalized());
		polys_colors.push_back(c);
	}
};

class LineSegments : public RenderObject::Base{
	QVector< QPair<QVector3,QVector3> > lines;
	QVector< QColor > lines_colors;
public:
	LineSegments():RenderObject::Base(1, Qt::black){}

    void draw(QGLWidget &widget){ this->draw(); Q_UNUSED(widget) }

	void draw(){
		glDisable(GL_LIGHTING);

		glLineWidth(_size);
		glBegin(GL_LINES);
		for(int i = 0; i < (int) lines.size(); i++){
			glColorQt(lines_colors[i]);
			glVertQt(lines[i].first);
			glVertQt(lines[i].second);
		}
		glEnd();

		glPointSize(_size+2);
		glBegin(GL_POINTS);
		for(int i = 0; i < (int) lines.size(); i++){
			glColorQt(lines_colors[i]);
			glVertQt(lines[i].first);
		}
		glEnd();

		glEnable(GL_LIGHTING);
	}

	void addLine(const QVector3& p1, const QVector3& p2, const QColor& c = Qt::blue){
		lines.push_back( qMakePair(p1,p2) );
		lines_colors.push_back(c);
	}

	void addLines()
	{

	}
};

class PointSoup : public RenderObject::Base{
	QVector< QVector3 > points;
	QVector< QVector3 > normals;
	QVector< QColor > points_colors;
public:
	PointSoup(float size = 6.0f):RenderObject::Base(size, Qt::black){}

	void clear(){
		points.clear();
		points_colors.clear();
	}

    void draw(QGLWidget &widget){ this->draw(); Q_UNUSED(widget) }

	void draw(){
		glDisable(GL_LIGHTING);
		if(normals.size()) glEnable(GL_LIGHTING);

		glPointSize(_size);
		glBegin(GL_POINTS);
		for(int i = 0; i < (int) points.size(); i++){
			if(normals.size()) glNormal3d(normals[i].x(),normals[i].y(),normals[i].z());
			glColorQt(points_colors[i]);
			glVertQt(points[i]);
		}
		glEnd();

		glEnable(GL_LIGHTING);
	}

	void addPointNormal(const QVector3& p, const QVector3& n, const QColor& c = Qt::blue){
		addPoint(p,c);
		normals.push_back(n);
	}

	void addPoint(const QVector3& p, const QColor& c = Qt::blue){
		points.push_back(p);
		points_colors.push_back(c);
	}

    size_t count(){
        return points.size();
    }
};

class VectorSoup : public RenderObject::Base{
    QVector< QPair<QVector3,QVector3> > vectors;
    QVector< double > vectorLengths;
    double maxLen;
public:
    VectorSoup(const QColor& c = Qt::green):RenderObject::Base(1, c){ maxLen = -DBL_MAX; }

	void clear(){
		vectors.clear();
		vectorLengths.clear();
		maxLen = -DBL_MAX;
	}

    void addVector(const QVector3& start, const QVector3& direction){
        vectors.push_back( qMakePair(start,direction) );
        double l = direction.length();
        vectorLengths.push_back(l);
        maxLen = qMax(l,maxLen);
    }

    void draw(QGLWidget &widget){ this->draw(); Q_UNUSED(widget) }

    void draw(float thickness = 1.0f){
        glDisable(GL_LIGHTING);
        glLineWidth(thickness);
        glBegin(GL_LINES);
        for(int i = 0; i < (int) vectors.size(); i++){
            // Color
            //double d = vectorLengths[i] / maxLen;
            //QColor c( _color.red() * d, _color.green() * d, _color.blue() * d );
            glColorQt(this->_color.lighter());

            // Line
            glVertQt(vectors[i].first);
            glVertQt((vectors[i].first + vectors[i].second));
        }
        glEnd();

        glPointSize(thickness * 2);
        glBegin(GL_POINTS);
        for(int i = 0; i < (int) vectors.size(); i++){
            // Color
            //double d = vectorLengths[i] / maxLen;
            //QColor c( _color.red() * d, _color.green() * d, _color.blue() * d );
            glColorQt(this->_color);

            // Point
            glVertQt((vectors[i].first + vectors[i].second));
        }
        glEnd();
        glEnable(GL_LIGHTING);
    }
};


class PlaneSoup : public RenderObject::Base{
	QVector< QPair<QVector3,QVector3> > planes;
	double scale;
public:
	PlaneSoup(double s = 1.0, const QColor& c = Qt::green):RenderObject::Base(1, c)
	{ scale = s; }

	void addPlane(const QVector3& center, const QVector3& normal){
		planes.push_back( qMakePair(center, normal) );
	}

	void draw(QGLWidget &widget){this->draw();widget;}

	void draw(){
		glDisable(GL_LIGHTING);

		// Rendering options
		glEnable (GL_POINT_SMOOTH);
		glEnable (GL_LINE_SMOOTH);
		glEnable (GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glHint (GL_LINE_SMOOTH_HINT, GL_NICEST);

		float color[4];
		glGetFloatv(GL_CURRENT_COLOR, color);

		// Bake geometry
		int c = planes.size();
		std::vector<QVector3> n(c),u(c),v(c),p1(c),p2(c),p3(c),p4(c);
		for(int i = 0; i < c; i++){
			n[i] = planes[i].second;
			u[i] = scale * orthogonalVector(n[i]).normalized();
			v[i] = scale * QVector3D::crossProduct(n[i], u[i]).normalized();

			p1[i] = QVector3(planes[i].first + (u[i] + v[i]));
			p2[i] = QVector3(planes[i].first + (-u[i] + v[i]));
			p3[i] = QVector3(planes[i].first + (-v[i] + u[i]));
			p4[i] = QVector3(planes[i].first + (-v[i] + -u[i]));
		}

		// Draw Borders
		glColor4f(color[0]*0.8, color[1]*0.8, color[2]*0.8, 0.5);
		glLineWidth(2.0);
		glPolygonMode(GL_FRONT,GL_LINE);
		glBegin(GL_QUADS);
		for(int i = 0; i < c; i++)
		{
			glVertQt(p1[i]);
			glVertQt(p2[i]);
			glVertQt(p4[i]);
			glVertQt(p3[i]);
		}
		glEnd();

		// Draw Center
		glColor3f(color[0], color[1], color[2]);
		glPointSize(4.0);
		glBegin(GL_POINTS);
		for(int i = 0; i < c; i++) glVertQt(planes[i].first);
		glEnd();
		glPointSize(8.0);
		glColor4f(1, 1, 1, 0.5);
		glBegin(GL_POINTS);
		for(int i = 0; i < c; i++) glVertQt(planes[i].first);
		glEnd();

		// Draw Normal
		glBegin(GL_LINES);
		for(int i = 0; i < c; i++)
		{
			Vector3d center = planes[i].first;
			glv(center);
			glv(Vector3(center + ((Vector3d)n[i] * 0.2 * scale)));
		}
		glEnd();

		// Draw Transparent Fills
		glColor4f(color[0], color[1], color[2], 0.05f);
		glPolygonMode(GL_FRONT,GL_FILL);
		glBegin(GL_QUADS);
		for(int i = 0; i < c; i++)
		{
			glVertQt(p1[i]);
			glVertQt(p2[i]);
			glVertQt(p4[i]);
			glVertQt(p3[i]);
		}
		glEnd();

		glDisable(GL_BLEND);
		glEnable(GL_LIGHTING);
	}

	static QVector3 orthogonalVector(const QVector3& n) {
		if ((abs(n.y()) >= 0.9 * abs(n.x())) &&
			abs(n.z()) >= 0.9 * abs(n.x())) return QVector3(0.0, -n.z(), n.y());
		else if ( abs(n.x()) >= 0.9 * abs(n.y()) &&
			abs(n.z()) >= 0.9 * abs(n.y()) ) return QVector3(-n.z(), 0.0, n.x());
		else return QVector3(-n.y(), n.x(), 0.0);
	}
};

class FrameSoup : public RenderObject::Base{
	QVector< QVector<QVector3> > frames;
	bool isFlip;

public:
	FrameSoup(float scale, bool flip = false, const QColor& c = Qt::green):RenderObject::Base(scale, c)
	{
		this->isFlip = flip;
	}

	void addFrame(const QVector3& X, const QVector3& Y, const QVector3& Z, const QVector3& position){
		QVector<QVector3> frame;
		if(isFlip)
		{
			frame.push_back(Z);
			frame.push_back(Y);
			frame.push_back(X);
		}
		else
		{
			frame.push_back(X);
			frame.push_back(Y);
			frame.push_back(Z);
		}
		frame.push_back(position);
		frames.push_back(frame);
	}

    void draw(QGLWidget &widget){ this->draw(); Q_UNUSED(widget) }

	void draw()
	{
		drawFrame();
	}

	void drawFrame( int colorOffset = 0 )
	{
		QColor frameColors[] = { QColor(255,0,0), QColor(0,255,0), QColor(0,0,255) };
		int ci = colorOffset;

		glDisable(GL_LIGHTING);
		glLineWidth(1);
		glBegin(GL_LINES);
		for(int i = 0; i < (int) frames.size(); i++){
			QVector3 X=frames[i][0],Y=frames[i][1],Z=frames[i][2];
			QVector3 pos=frames[i][3];
			glColorQt(frameColors[(ci+0)%3]); glVertQt(pos); glVertQt((pos + X * _size));
			glColorQt(frameColors[(ci+1)%3]); glVertQt(pos); glVertQt((pos + Y * _size));
			glColorQt(frameColors[(ci+2)%3]); glVertQt(pos); glVertQt((pos + Z * _size));
		}
		glEnd();

		glPointSize(3);
		glBegin(GL_POINTS);
		for(int i = 0; i < (int) frames.size(); i++){
			QVector3 X=frames[i][0],Y=frames[i][1],Z=frames[i][2];
			QVector3 pos=frames[i][3];
			glColorQt(frameColors[(ci+0)%3]); glVertQt((pos + X * _size));
			glColorQt(frameColors[(ci+1)%3]); glVertQt((pos + Y * _size));
			glColorQt(frameColors[(ci+2)%3]); glVertQt((pos + Z * _size));
		}
		glEnd();
		glEnable(GL_LIGHTING);
	}
};

static void renderSphere(float cx, float cy, float cz, float r)
{
	#ifndef M_PI
	#define M_PI       3.14159265358979323846
	#endif

	#ifndef M_PI_2
	#define M_PI_2     1.57079632679489661923
	#endif

	const int p = 24;

	float theta1 = 0.0, theta2 = 0.0, theta3 = 0.0;
	float ex = 0.0f, ey = 0.0f, ez = 0.0f;
	float px = 0.0f, py = 0.0f, pz = 0.0f;
	GLfloat vertices[p*6+6], normals[p*6+6], texCoords[p*4+4];

	for(int i = 0; i < p/2; ++i){
		theta1 = i * (M_PI*2) / p - M_PI_2;
		theta2 = (i + 1) * (M_PI*2) / p - M_PI_2;

		for(int j = 0; j <= p; ++j){
			theta3 = j * (M_PI*2) / p;

			ex = cosf(theta2) * cosf(theta3);
			ey = sinf(theta2);
			ez = cosf(theta2) * sinf(theta3);
			px = cx + r * ex;
			py = cy + r * ey;
			pz = cz + r * ez;

			vertices[(6*j)+(0%6)] = px;
			vertices[(6*j)+(1%6)] = py;
			vertices[(6*j)+(2%6)] = pz;

			normals[(6*j)+(0%6)] = ex;
			normals[(6*j)+(1%6)] = ey;
			normals[(6*j)+(2%6)] = ez;

			texCoords[(4*j)+(0%4)] = -(j/(float)p);
			texCoords[(4*j)+(1%4)] = 2*(i+1)/(float)p;

			ex = cosf(theta1) * cosf(theta3);
			ey = sinf(theta1);
			ez = cosf(theta1) * sinf(theta3);
			px = cx + r * ex;
			py = cy + r * ey;
			pz = cz + r * ez;

			vertices[(6*j)+(3%6)] = px;
			vertices[(6*j)+(4%6)] = py;
			vertices[(6*j)+(5%6)] = pz;

			normals[(6*j)+(3%6)] = ex;
			normals[(6*j)+(4%6)] = ey;
			normals[(6*j)+(5%6)] = ez;

			texCoords[(4*j)+(2%4)] = -(j/(float)p);
			texCoords[(4*j)+(3%4)] = 2*i/(float)p;
		}

		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glEnableClientState(GL_NORMAL_ARRAY);
		glEnableClientState(GL_VERTEX_ARRAY);

		glTexCoordPointer(2, GL_FLOAT, 0, texCoords);
		glNormalPointer(GL_FLOAT, 0, normals);
		glVertexPointer(3, GL_FLOAT, 0, vertices);

		glDrawArrays(GL_TRIANGLE_STRIP, 0, (p+1)*2);

		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_NORMAL_ARRAY);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY);
	}
}

class SphereSoup : public RenderObject::Base{
	QVector< QVector3 > centers;
	QVector< float > radii;
	QVector< QColor > colors;
public:
	SphereSoup(const QColor& c = Qt::yellow):RenderObject::Base(1, c){}

	void clear(){
		centers.clear();
		radii.clear();
		colors.clear();
	}

    void draw(QGLWidget &widget){ this->draw(); Q_UNUSED(widget) }

	void draw(){
		glEnable(GL_LIGHTING);
		for(int i = 0; i < (int) centers.size(); i++){
			Vector3d c = centers[i];
			glColorQt(colors[i]);
			renderSphere(c[0],c[1],c[2],radii[i]);
		}
	}

	void addSphere(const QVector3& center, float radius = 0.1f){
		centers.push_back(center);
		radii.push_back(radius);
		colors.push_back(_color);
	}

	void addSphere(const QVector3& center, float radius, const QColor& c){
		centers.push_back(center);
		radii.push_back(radius);
		colors.push_back(c);
	}
};

class CubeSoup : public RenderObject::Base{
	QVector< QVector3 > centers;
	QVector< float > lengths;
	QVector< QColor > colors;
	bool isWireframe;

public:
	CubeSoup(float defaultSize = 1.0, bool is_wireframe = true):RenderObject::Base(defaultSize, Qt::black)
	{ isWireframe = is_wireframe; }

	void clear(){
		centers.clear();
		lengths.clear();
		colors.clear();
	}

	void drawCube(QVector3 center, double length = 1.0)
	{
		static GLdouble n[6][3] =
		{{-1.0, 0.0, 0.0},
		{0.0, 1.0, 0.0},
		{1.0, 0.0, 0.0},
		{0.0, -1.0, 0.0},
		{0.0, 0.0, 1.0},
		{0.0, 0.0, -1.0}};

		static GLint faces[6][4] =
		{{0, 1, 2, 3},
		{3, 2, 6, 7},
		{7, 6, 5, 4},
		{4, 5, 1, 0},
		{5, 6, 2, 1},
		{7, 4, 0, 3}};

		GLdouble v[8][3]; GLint i;

		v[0][0] = v[1][0] = v[2][0] = v[3][0] = -length / 2;
		v[4][0] = v[5][0] = v[6][0] = v[7][0] = length / 2;
		v[0][1] = v[1][1] = v[4][1] = v[5][1] = -length / 2;
		v[2][1] = v[3][1] = v[6][1] = v[7][1] = length / 2;
		v[0][2] = v[3][2] = v[4][2] = v[7][2] = -length / 2;
		v[1][2] = v[2][2] = v[5][2] = v[6][2] = length / 2;

		glPushMatrix();
		glTranslatef(center.x(), center.y(), center.z());

		for (i = 0; i < 6; i++) 
		{
			glBegin(GL_QUADS);
			glNormal3dv(&n[i][0]);
			glVertex3dv(&v[faces[i][0]][0]);
			glVertex3dv(&v[faces[i][1]][0]);
			glVertex3dv(&v[faces[i][2]][0]);
			glVertex3dv(&v[faces[i][3]][0]);
			glEnd();
		}

		glPopMatrix();
	}

    void draw(QGLWidget &widget){ this->draw(); Q_UNUSED(widget) }

	void draw()
	{
		glEnable(GL_LIGHTING);
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
		
		if(isWireframe){
			glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
			glDisable(GL_LIGHTING);
		}

		for(int i = 0; i < (int) centers.size(); i++){
			glColorQt(colors[i]);
			drawCube(centers[i],lengths[i]);
		}

		glEnable(GL_LIGHTING);
		glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
	}

	void addCube(const QVector3& center, float length = 1, const QColor& c = Qt::yellow){
		centers.push_back(center);
		lengths.push_back(length * _size);
		colors.push_back(c);
	}
};

static QColor qtColdColor(double value, double min = 0.0, double max = 1.0){
	unsigned char rgb[3];
	value-=min;
	if(value==HUGE_VAL)
	{rgb[0]=rgb[1]=rgb[2]=255;}
	else if(value<0)
	{rgb[0]=rgb[1]=rgb[2]=0;}
	else if(value<max)
	{rgb[0]=0;rgb[1]=0;rgb[2]=(unsigned char)(255*value/max);}
	else {rgb[0]=rgb[1]=0;rgb[2]=255;}
	return QColor(rgb[0],rgb[1],rgb[2]);
}

static QColor qtJetColorMap(double value, double min = 0.0, double max = 1.0)
{
    unsigned char rgb[3];
    unsigned char c1=144;
    float max4=(max-min)/4;
    value-=min;
    if(value==HUGE_VAL)
    {rgb[0]=rgb[1]=rgb[2]=255;}
    else if(value<0)
    {rgb[0]=rgb[1]=rgb[2]=0;}
    else if(value<max4)
    {rgb[0]=0;rgb[1]=0;rgb[2]=c1+(unsigned char)((255-c1)*value/max4);}
    else if(value<2*max4)
    {rgb[0]=0;rgb[1]=(unsigned char)(255*(value-max4)/max4);rgb[2]=255;}
    else if(value<3*max4)
    {rgb[0]=(unsigned char)(255*(value-2*max4)/max4);rgb[1]=255;rgb[2]=255-rgb[0];}
    else if(value<max)
    {rgb[0]=255;rgb[1]=(unsigned char)(255-255*(value-3*max4)/max4);rgb[2]=0;}
    else {rgb[0]=255;rgb[1]=rgb[2]=0;}
    return QColor(rgb[0],rgb[1],rgb[2]);
}

#include <time.h>
static std::vector<double> randomColor()
{
    std::vector<double> color;

    float r = float( qMin(((rand() % 225) + 30), 255) ) / 255.0f;
    float g = float( qMin(((rand() % 230) + 25), 255) ) / 255.0f;
    float b = float( qMin(((rand() % 235) + 20), 255) ) / 255.0f;

    color.push_back(r);
    color.push_back(g);
    color.push_back(b);
    color.push_back(1.0);

    return color;
}

static std::vector< std::vector<double> > randomColors( int count )
{
	srand(time(NULL));

	std::vector< std::vector<double> > colors(count);
    for (int i = 0; i < count; i++)
        colors[i] = randomColor();
	return colors;
}

static QColor qRandomColor()
{
    std::vector<double> c = randomColor();
    return QColor::fromRgbF( c[0], c[1], c[2], c[3] );
}

static QColor qRandomColor2(double saturation = 0.5, double val = 0.95)
{
	double golden_ratio_conjugate = 0.618033988749895;
	double h = ((double)rand() / RAND_MAX);
	h += golden_ratio_conjugate;
	h = fmod(h, 1.0);
	return QColor::fromHsvF(h, saturation, val);
}

// Helper functions
double inline uniformRand(double a = 0.0, double b = 1.0){
	double len = b - a;
	return ((double)rand()/RAND_MAX) * len + a;
}

// for mid = 0, colors are centered around Red
static QColor qRandomColor3(double mid = 0, double range = 0.5, double saturation = 1.0, double val = 1.0)
{
	// Bound checks
	mid = qMax(0.0, qMin(1.0, mid));
	range = qMin(0.5, range);

	double h = uniformRand( -range + mid, range + mid );

	h = fmod(1.0 + h, 1.0);

	return QColor::fromHsvF(h, saturation, val);
}

Software Heritage — Copyright (C) 2015–2025, The Software Heritage developers. License: GNU AGPLv3+.
The source code of Software Heritage itself is available on our development forge.
The source code files archived by Software Heritage are available under their own copyright and licenses.
Terms of use: Archive access, API— Contact— JavaScript license information— Web API

back to top