Je trouve l'algorithme suivant pour générer un polygone décrit:Qu'est-ce qu'un calcul d'onglet interne?
void CGlShape::GenerateLinePoly(std::vector<DOUBLEPOINT> &input, int width)
{
OutlineVec.clear();
if(input.size() < 2)
{
return;
}
if(connected)
{
input.push_back(input[0]);
input.push_back(input[1]);
}
float w = width/2.0f;
//glBegin(GL_TRIANGLES);
for(size_t i = 0; i < input.size()-1; ++i)
{
POINTFLOAT cur;
cur.x = input[i].point[0];
cur.y = input[i].point[1];
POINTFLOAT nxt;
nxt.x = input[i+1].point[0];
nxt.y = input[i+1].point[1];
POINTFLOAT b;
b.x = nxt.x - cur.x;
b.y = nxt.y - cur.y;
b = normalize(b);
POINTFLOAT b_perp;
b_perp.x = -b.y;
b_perp.y = b.x;
POINTFLOAT p0;
POINTFLOAT p1;
POINTFLOAT p2;
POINTFLOAT p3;
p0.x = cur.x + b_perp.x * w;
p0.y = cur.y + b_perp.y * w;
p1.x = cur.x - b_perp.x * w;
p1.y = cur.y - b_perp.y * w;
p2.x = nxt.x + b_perp.x * w;
p2.y = nxt.y + b_perp.y * w;
p3.x = nxt.x - b_perp.x * w;
p3.y = nxt.y - b_perp.y * w;
OutlineVec.push_back(p0.x);
OutlineVec.push_back(p0.y);
OutlineVec.push_back(p1.x);
OutlineVec.push_back(p1.y);
OutlineVec.push_back(p2.x);
OutlineVec.push_back(p2.y);
OutlineVec.push_back(p2.x);
OutlineVec.push_back(p2.y);
OutlineVec.push_back(p1.x);
OutlineVec.push_back(p1.y);
OutlineVec.push_back(p3.x);
OutlineVec.push_back(p3.y);
// only do joins when we have a prv
if(i == 0) continue;
POINTFLOAT prv;
prv.x = input[i-1].point[0];
prv.y = input[i-1].point[1];
POINTFLOAT a;
a.x = prv.x - cur.x;
a.y = prv.y - cur.y;
a = normalize(a);
POINTFLOAT a_perp;
a_perp.x = a.y;
a_perp.y = -a.x;
float det = a.x * b.y - b.x * a.y;
if(det > 0)
{
a_perp.x = -a_perp.x;
a_perp.y = -a_perp.y;
b_perp.x = -b_perp.x;
b_perp.y = -b_perp.y;
}
// TODO: do inner miter calculation
// flip around normals and calculate round join points
a_perp.x = -a_perp.x;
a_perp.y = -a_perp.y;
b_perp.x = -b_perp.x;
b_perp.y = -b_perp.y;
size_t num_pts = 16;
std::vector< POINTFLOAT> round(1 + num_pts + 1);
POINTFLOAT nc;
nc.x = cur.x + (a_perp.x * w);
nc.y = cur.y + (a_perp.y * w);
round.front() = nc;
nc.x = cur.x + (b_perp.x * w);
nc.y = cur.y + (b_perp.y * w);
round.back() = nc;
for(size_t j = 1; j < num_pts+1; ++j)
{
float t = (float)j/(float)(num_pts+1);
if(det > 0)
{
POINTFLOAT nin;
nin = slerp2d(b_perp, a_perp, 1.0f-t);
nin.x *= w;
nin.y *= w;
nin.x += cur.x;
nin.y += cur.y;
round[j] = nin;
}
else
{
POINTFLOAT nin;
nin = slerp2d(a_perp, b_perp, t);
nin.x *= w;
nin.y *= w;
nin.x += cur.x;
nin.y += cur.y;
round[j] = nin;
}
}
for(size_t j = 0; j < round.size()-1; ++j)
{
OutlineVec.push_back(cur.x);
OutlineVec.push_back(cur.y);
if(det > 0)
{
OutlineVec.push_back(round[j + 1].x);
OutlineVec.push_back(round[j + 1].y);
OutlineVec.push_back(round[j].x);
OutlineVec.push_back(round[j].y);
}
else
{
OutlineVec.push_back(round[j].x);
OutlineVec.push_back(round[j].y);
OutlineVec.push_back(round[j + 1].x);
OutlineVec.push_back(round[j + 1].y);
}
}
}
}
POINTFLOAT multiply(const POINTFLOAT &a, float b)
{
POINTFLOAT result;
result.x = a.x * b;
result.y = a.y * b;
return result;
}
POINTFLOAT normalize(const POINTFLOAT &a)
{
return multiply(a, 1.0f/sqrt(a.x*a.x+a.y*a.y));
}
POINTFLOAT slerp2d(const POINTFLOAT &v0,
const POINTFLOAT &v1, float t)
{
float dot = (v0.x * v1.x + v0.y * v1.y);
if(dot < -1.0f) dot = -1.0f;
if(dot > 1.0f) dot = 1.0f;
float theta_0 = acos(dot);
float theta = theta_0 * t;
POINTFLOAT v2;
v2.x = -v0.y;
v2.y = v0.x;
POINTFLOAT result;
result.x = v0.x * cos(theta) + v2.x * sin(theta);
result.y = v0.y * cos(theta) + v2.y * sin(theta);
return result;
}
Il y a un commentaire disant que le calcul d'onglet intérieure doit être réalisée, mais je ne sais pas ce que cela est ou comment il devrait être fait. En ce moment, cet algorithme produit des arêtes arrondies, mais je voudrais le modifier pour faire des bords d'onglet (carrés) à la place, comment cela pourrait-il être fait? Cela implique-t-il un calcul d'onglet interne?
Merci
Ce code est assez pauvre pour lire, pourquoi il ne fonctionne pour fournir ces services de vecteur de base comme l'addition et négateur? Il y a une belle fonction 'multiply' qui n'est même pas utilisée pour se multiplier. De plus, il semble que certaines valeurs nous manquent aussi; D'où vient le 'w' dans le premier extrait? –
OK J'ai corrigé le code manquant – jmasterx
[Certains styles] (http://www.opengl.org/resources/code/samples/sig99/advanced99/notes/node281.html). Voulez-vous une mitre extérieure ou un biseau externe? – genpfault