www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

quad.cpp (6913B)


      1 #include "all_includes.hh"
      2 
      3 Quad::Quad() {}
      4 
      5 Quad::Quad(Vertex ne, Vertex se, Vertex sw, Vertex nw) {
      6 	c[(int)NE] = ne;
      7 	c[(int)SE] = se;
      8 	c[(int)SW] = sw;
      9 	c[(int)NW] = nw;
     10 }
     11 
     12 Quad Quad::inset(Cardinal side, float offset) const {
     13 	Quad q = (*this) << int(side);
     14 	Vertex offsetDirection = Triangle(q[NE], q[NW], q[NW] + q.normal()).normal();
     15 	Vertex e = q[SE] - q[NE];
     16 	Vertex w = q[SW] - q[NW];
     17 	float distE = offset / offsetDirection.cosAngle(e);
     18 	float distW = offset / offsetDirection.cosAngle(w);
     19 	q[NE] = q[NE] + e.setNorm(distE);
     20 	q[NW] = q[NW] + w.setNorm(distW);
     21 	return q >> int(side);
     22 }
     23 
     24 Quad Quad::insetNESW(float offsetN, float offsetE, float offsetS, float offsetW) const {
     25     return (*this).inset(N,offsetN).inset(E,offsetE).inset(S,offsetS).inset(W,offsetW);
     26 }
     27 
     28 Quad Quad::insetNESW(float offset) const {
     29 	return insetNESW(offset, offset, offset, offset);
     30 }
     31 
     32 Quad Quad::insetOpp(Cardinal side, float offset) const {
     33     Quad q = (*this) << side;
     34     Quad qi = q.inset(N,offset);
     35     return (Quad(q[NE],qi[NE],qi[NW],q[NW]) >> side);
     36 }
     37 
     38 Quad Quad::makeParallelogram() const {
     39     float l1, l2;
     40     Quad q(c[NE],c[SE],c[SW],c[NW]);
     41 
     42     if(length(N) < length(S)) {
     43         if((l1 = length(E)) < (l2 = length(W))) {
     44             q[SW] = Segment(q[NW],q[SW]).reduce(l1).v;
     45             q[SE] = q[SW] + (q[NE] - q[NW]);
     46         }
     47         else if((l1 = length(E)) > (l2 = length(W))) {
     48             q[SE] = Segment(q[NE],q[SE]).reduce(l2).v;
     49             q[SW] = q[SE] + (q[NW] - q[NE]);
     50         }
     51     }
     52     else {
     53         if((l1 = length(E)) < (l2 = length(W))) {
     54             q[NW] = Segment(q[SW],q[NW]).reduce(l1).v;
     55             q[NE] = q[NW] + (q[SE] - q[SW]);
     56         }
     57         else if((l1 = length(E)) > (l2 = length(W))) {
     58             q[NE] = Segment(q[SE],q[NE]).reduce(l2).v;
     59             q[NW] = q[NE] + (q[SW] - q[SE]);
     60         }
     61     }
     62 
     63     return q;
     64 }
     65 
     66 float Quad::length(Cardinal side) const {
     67 	return Segment(c[NW+int(side)],c[NE+int(side)]).length();
     68 }
     69 
     70 float Quad::minLengthNS() const {
     71 	return std::min(length(N), length(S));
     72 }
     73 
     74 float Quad::minLengthEW() const {
     75 	return std::min(length(E), length(W));
     76 }
     77 
     78 float Quad::maxLengthNS() const {
     79 	return std::max(length(N), length(S));
     80 }
     81 
     82 float Quad::maxLengthEW() const {
     83 	return std::max(length(E), length(W));
     84 }
     85 
     86 float Quad::minLength() const {
     87 	return std::min(minLengthNS(), minLengthEW());
     88 }
     89 
     90 float Quad::maxLength() const {
     91 	return std::max(maxLengthNS(), maxLengthEW());
     92 }
     93 
     94 Cardinal Quad::minLengthSide() const {
     95 	float ln = length(N);
     96 	float le = length(E);
     97 	float ls = length(S);
     98 	float lw = length(W);
     99 	if (ln < le && ln < ls && ln < lw) return N;
    100 	else if (le < ls && le < lw) return E;
    101 	else if (ls < lw) return S;
    102 	else return W;
    103 }
    104 
    105 Cardinal Quad::maxLengthSide() const {
    106 	float ln = length(N);
    107 	float le = length(E);
    108 	float ls = length(S);
    109 	float lw = length(W);
    110 	if (ln > le && ln > ls && ln > lw) return N;
    111 	else if (le > ls && le > lw) return E;
    112 	else if (ls > lw) return S;
    113 	else return W;
    114 }
    115 
    116 float Quad::angle(Coin corner) const {
    117 	return Triangle(c[NW+corner], c[NE+corner], c[SE+corner]).angle();
    118 }
    119 
    120 float Quad::minAngle() const {
    121 	float ane = angle(NE);
    122 	float ase = angle(SE);
    123 	float asw = angle(SW);
    124 	float anw = 2*Angle::Pi - (ane + ase + asw);
    125 	return std::min(std::min(ane, ase), std::min(asw, anw));
    126 }
    127 
    128 float Quad::maxAngle() const {
    129 	float ane = angle(NE);
    130 	float ase = angle(SE);
    131 	float asw = angle(SW);
    132 	float anw = 2*Angle::Pi - (ane + ase + asw);
    133 	return std::max(std::max(ane, ase), std::max(asw, anw));
    134 }
    135 
    136 Coin Quad::minAngleCorner() const {
    137 	float ane = angle(NE);
    138 	float ase = angle(SE);
    139 	float asw = angle(SW);
    140 	float anw = 2*Angle::Pi - (ane + ase + asw);
    141 	if (ane < ase && ane < asw && ane < anw) return NE;
    142 	else if (ase < asw && ase < anw) return SE;
    143 	else if (asw < anw) return SW;
    144 	else return NW;
    145 }
    146 
    147 Coin Quad::maxAngleCorner() const {
    148 	float ane = angle(NE);
    149 	float ase = angle(SE);
    150 	float asw = angle(SW);
    151 	float anw = 2*Angle::Pi - (ane + ase + asw);
    152 	if (ane > ase && ane > asw && ane > anw) return NE;
    153 	else if (ase > asw && ase > anw) return SE;
    154 	else if (asw > anw) return SW;
    155 	else return NW;
    156 }
    157 
    158 Coin Quad::concaveCorner() {
    159     Vertex nne = Triangle(c[NW], c[NE], c[SE]).normalizedNormal();
    160     Vertex nse = Triangle(c[NE], c[SE], c[SW]).normalizedNormal();
    161     Vertex nsw = Triangle(c[SE], c[SW], c[NW]).normalizedNormal();
    162     Vertex nnw = Triangle(c[SW], c[NW], c[NE]).normalizedNormal();
    163 
    164     float dne1 = (nnw - nne).norm();
    165     float dne2 = (nse - nne).norm();
    166     float dse1 = (nne - nse).norm();
    167     float dse2 = (nsw - nse).norm();
    168     float dsw1 = (nse - nsw).norm();
    169     float dsw2 = (nnw - nsw).norm();
    170     float dnw1 = (nsw - nnw).norm();
    171     float dnw2 = (nne - nnw).norm();
    172 
    173     if(dne1 >= 1.5 && dne2 >= 1.5)
    174         return NE;
    175     else if(dse1 >= 1.5 && dse2 >= 1.5)
    176         return SE;
    177     else if(dsw1 >= 1.5 && dsw2 >= 1.5)
    178         return SW;
    179     else if(dnw1 >= 1.5 && dnw2 >= 1.5)
    180         return NW;
    181     else
    182     	return maxAngleCorner();
    183 }
    184 
    185 bool Quad::isConcave() {
    186     Vertex nne = Triangle(c[NW], c[NE], c[SE]).normalizedNormal();
    187     Vertex nse = Triangle(c[NE], c[SE], c[SW]).normalizedNormal();
    188     Vertex nsw = Triangle(c[SE], c[SW], c[NW]).normalizedNormal();
    189     Vertex nnw = Triangle(c[SW], c[NW], c[NE]).normalizedNormal();
    190 
    191     float dne1 = (nnw - nne).norm();
    192     float dse1 = (nne - nse).norm();
    193     float dsw1 = (nse - nsw).norm();
    194     float dnw1 = (nsw - nnw).norm();
    195 
    196     if(dne1 >= 1.5 || dse1 >= 1.5 || dsw1 >= 1.5 || dnw1 >= 1.5)
    197         return true;
    198 
    199     return (maxAngle() > Angle::d2r(160));
    200 }
    201 
    202 Quad operator+(const Quad& q, const Vertex& v) {
    203 	return Quad(q[NE] + v, q[SE] + v, q[SW] + v, q[NW] + v);
    204 }
    205 
    206 Vertex Quad::randomPoint(int seed, int n) const {
    207 	Triangle ne(c[NW], c[NE], c[SE]);
    208 	Triangle sw(c[SE], c[SW], c[NW]);
    209 	float surfacene = ne.surface();
    210 	float surfacesw = sw.surface();
    211 	if (proba(seed, n, surfacene / (surfacene + surfacesw))) {
    212 		return ne.randomPoint(seed, hash2(n, 42));
    213 	} else {
    214 		return sw.randomPoint(seed, hash2(n, 42));
    215 	}
    216 }
    217 
    218 float Quad::surface() const {
    219 	Triangle ne(c[NW], c[NE], c[SE]);
    220 	Triangle sw(c[SE], c[SW], c[NW]);
    221 	return ne.surface() + sw.surface();
    222 }
    223 
    224 Quad Quad::insetProportionnal(float prop) {
    225     Quad rQuad= *this;
    226 
    227     Vertex bc = Segment(Segment(c[NW],c[NE]).center(),Segment(c[SW],c[SE]).center()).center();
    228 
    229     rQuad[NW] = Segment(bc,c[NW]).at(prop);
    230     rQuad[NE] = Segment(bc,c[NE]).at(prop);
    231     rQuad[SE] = Segment(bc,c[SE]).at(prop);
    232     rQuad[SW] = Segment(bc,c[SW]).at(prop);
    233     return rQuad;
    234 }
    235 
    236 Quad Quad::offsetNormal(float offset) const {
    237 	return ((*this) + Triangle(c[NE], c[SE], c[SW]).normal().setNorm(offset));
    238 }
    239 
    240 Vertex Quad::normal() const {
    241 	return Triangle(c[NE], c[SE], c[SW]).normal();
    242 }
    243 
    244 Vertex Quad::normalizedNormal() const {
    245 	return Triangle(c[NE], c[SE], c[SW]).normalizedNormal();
    246 }
    247 
    248 Vertex Quad::moyenne() const {
    249 	return ((c[NE] + c[SE] + c[SW] + c[NW]) / 4.f);
    250 }