120 lines
3.3 KiB
C++
120 lines
3.3 KiB
C++
Triangle::Triangle() {
|
|
}
|
|
Triangle::Triangle(Vertex left, Vertex top, Vertex right) {
|
|
c[LEFT] = left;
|
|
c[TOP] = top;
|
|
c[RIGHT] = right;
|
|
}
|
|
|
|
float Triangle::cosAngle() const {
|
|
return (c[LEFT]-c[TOP]).cosAngle(c[RIGHT]-c[TOP]);
|
|
}
|
|
|
|
float Triangle::angle() const {
|
|
// TODO : gérer le cas d'un angle à 0 ou 180.
|
|
return std::acos(cosAngle());
|
|
}
|
|
|
|
float Triangle::minAngle() const {
|
|
float at = angle();
|
|
float ar = Triangle(c[TOP],c[RIGHT],c[LEFT]).angle();
|
|
float al = Angle::Pi - at - ar;
|
|
return std::min(std::min(al, at), ar);
|
|
}
|
|
|
|
float Triangle::maxAngle() const {
|
|
float at = angle();
|
|
float ar = Triangle(c[TOP],c[RIGHT],c[LEFT]).angle();
|
|
float al = Angle::Pi - at - ar;
|
|
return std::max(std::max(al, at), ar);
|
|
}
|
|
|
|
SommetTriangle Triangle::maxAngleCorner() const {
|
|
float at = angle();
|
|
float ar = Triangle(c[TOP],c[RIGHT],c[LEFT]).angle();
|
|
float al = Angle::Pi - at - ar;
|
|
if (al > at && al > ar) return LEFT;
|
|
else if (at > ar) return TOP;
|
|
else return RIGHT;
|
|
}
|
|
|
|
SommetTriangle Triangle::minAngleCorner() const {
|
|
float at = angle();
|
|
float ar = Triangle(c[TOP],c[RIGHT],c[LEFT]).angle();
|
|
float al = Angle::Pi - at - ar;
|
|
if (al < at && al < ar) return LEFT;
|
|
else if (at < ar) return TOP;
|
|
else return RIGHT;
|
|
}
|
|
|
|
float Triangle::minLength() const {
|
|
return std::min(std::min((c[LEFT] - c[TOP]).norm(), (c[TOP] - c[RIGHT]).norm()), (c[RIGHT] - c[LEFT]).norm());
|
|
}
|
|
|
|
float Triangle::maxLength() const {
|
|
return std::max(std::max((c[LEFT] - c[TOP]).norm(), (c[TOP] - c[RIGHT]).norm()), (c[RIGHT] - c[LEFT]).norm());
|
|
}
|
|
|
|
Triangle Triangle::inset(CoteTriangle side, float offset) const {
|
|
Triangle t = (*this) << int(side);
|
|
Vertex offsetDirection = Triangle(t[TOP], t[LEFT], t[LEFT] + t.normal()).normal();
|
|
Vertex rightside = t[RIGHT] - t[TOP];
|
|
Vertex base = t[RIGHT] - t[LEFT];
|
|
float distTR = offset / offsetDirection.cosAngle(rightside);
|
|
float distLR = offset / offsetDirection.cosAngle(base);
|
|
t[TOP] = t[TOP] + rightside.setNorm(distTR);
|
|
t[LEFT] = t[LEFT] + base.setNorm(distLR);
|
|
return t >> int(side);
|
|
}
|
|
|
|
Triangle Triangle::insetLTR(float offset) const {
|
|
return (*this).inset(LEFTSIDE, offset).inset(RIGHTSIDE, offset).inset(BASE, offset);
|
|
}
|
|
|
|
Triangle operator+(const Triangle& t, const Vertex& v) {
|
|
return Triangle(t[LEFT] + v, t[TOP] + v, t[RIGHT] + v);
|
|
}
|
|
|
|
Vertex Triangle::randomPoint(int seed, int n) const {
|
|
float rndl = floatInRange(seed, n, 0, 1);
|
|
float rndr = floatInRange(seed, hash2(n, 42), 0, 1 - rndl);
|
|
return c[TOP] + (c[LEFT] - c[TOP]) * (rndl) + (c[RIGHT] - c[TOP]) * (rndr);
|
|
}
|
|
|
|
float Triangle::surface() const {
|
|
float hauteur = Segment(c[TOP], c[LEFT] + (c[TOP] - c[LEFT]).projectOn(c[RIGHT] - c[LEFT])).length();
|
|
float base = Segment(c[LEFT], c[RIGHT]).length();
|
|
return (base * hauteur) / 2.f;
|
|
}
|
|
|
|
Vertex Triangle::normal() const {
|
|
return ((c[LEFT] - c[TOP]) * (c[RIGHT] - c[TOP]));
|
|
}
|
|
|
|
Vertex Triangle::normalizedNormal() const {
|
|
Vertex v = normal();
|
|
return v / v.norm();
|
|
}
|
|
|
|
Triangle Triangle::offsetNormal(float offset) const {
|
|
return ((*this) + this->normal().setNorm(offset));
|
|
}
|
|
|
|
Triangle Triangle::insetProportionnal(float prop) {
|
|
Triangle rTriangle = *this;
|
|
//ibc : isobarycentre.
|
|
Vertex ibc = Segment(c[TOP],Segment(c[LEFT],c[RIGHT]).center()).at(2.f/3.f);
|
|
prop = prop;
|
|
|
|
rTriangle[TOP] = Segment(ibc,c[TOP]).at(prop);
|
|
rTriangle[LEFT] = Segment(ibc,c[LEFT]).at(prop);
|
|
rTriangle[RIGHT] = Segment(ibc,c[RIGHT]).at(prop);
|
|
return rTriangle;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|