[692] | 1 | #include <math.h>
|
---|
| 2 | #include "lwPolygon.h"
|
---|
| 3 | #include "BitArray.h"
|
---|
| 4 |
|
---|
| 5 | const float epsilon = 0.001F; // error margin
|
---|
| 6 |
|
---|
| 7 | void lwPolygon::flip(void)
|
---|
| 8 | {
|
---|
| 9 | vvertices flipvertices;
|
---|
| 10 | flipvertices.reserve(vertices.size());
|
---|
| 11 | vvertices::reverse_iterator i = vertices.rbegin();
|
---|
| 12 | vvertices::reverse_iterator end = vertices.rend();
|
---|
| 13 | for(; i!=end ; ++i)
|
---|
| 14 | flipvertices.push_back(*i);
|
---|
| 15 | vertices = flipvertices;
|
---|
| 16 | }
|
---|
| 17 |
|
---|
| 18 | lwPolygon *lwPolygon::makeTriangle(long ia, long ib, long ic)
|
---|
| 19 | {
|
---|
| 20 | lwPolygon *triangle = new lwPolygon(*this);
|
---|
| 21 |
|
---|
| 22 | triangle->vertices.push_back(new lwVertex(*vertices[ia]));
|
---|
| 23 | triangle->vertices.push_back(new lwVertex(*vertices[ib]));
|
---|
| 24 | triangle->vertices.push_back(new lwVertex(*vertices[ic]));
|
---|
| 25 |
|
---|
| 26 | return triangle;
|
---|
| 27 | }
|
---|
| 28 |
|
---|
| 29 | Vector3 &lwPolygon::calculateNormal()
|
---|
| 30 | {
|
---|
| 31 | if ( vertices.size() < 3 ) return normal;
|
---|
| 32 |
|
---|
| 33 | Point3 *p1 = vertices[ 0 ]->point;
|
---|
| 34 | Point3 *p2 = vertices[ 1 ]->point;
|
---|
| 35 | Point3 *pn = vertices[vertices.size() - 1]->point;
|
---|
| 36 |
|
---|
| 37 | normal = (*p2 - *p1).crossProduct(*pn - *p1);
|
---|
| 38 | normal.normalise();
|
---|
| 39 |
|
---|
| 40 | return normal;
|
---|
| 41 | }
|
---|
| 42 |
|
---|
| 43 | vpolygons lwPolygon::triangulate()
|
---|
| 44 | {
|
---|
| 45 | vpolygons triangles;
|
---|
| 46 |
|
---|
| 47 | BitArray active(vertices.size(), true); // vertex part of polygon ?
|
---|
| 48 |
|
---|
| 49 | long vertexCount = vertices.size();
|
---|
| 50 |
|
---|
| 51 | long triangleCount = 0;
|
---|
| 52 | long start = 0;
|
---|
| 53 |
|
---|
| 54 | long p1 = 0;
|
---|
| 55 | long p2 = 1;
|
---|
| 56 | long m1 = vertexCount - 1;
|
---|
| 57 | long m2 = vertexCount - 2;
|
---|
| 58 |
|
---|
| 59 | bool lastPositive = false;
|
---|
| 60 | for (;;)
|
---|
| 61 | {
|
---|
| 62 | if (p2 == m2)
|
---|
| 63 | {
|
---|
| 64 | triangles.push_back(makeTriangle(m1, p1, p2));
|
---|
| 65 | break;
|
---|
| 66 | }
|
---|
| 67 |
|
---|
| 68 | const Point3 vp1 = *vertices[p1]->point;
|
---|
| 69 | const Point3 vp2 = *vertices[p2]->point;
|
---|
| 70 | const Point3 vm1 = *vertices[m1]->point;
|
---|
| 71 | const Point3 vm2 = *vertices[m2]->point;
|
---|
| 72 |
|
---|
| 73 | bool positive = false;
|
---|
| 74 | bool negative = false;
|
---|
| 75 |
|
---|
| 76 | Vector3 n1 = normal.crossProduct((vm1 - vp2).normalise());
|
---|
| 77 | if (n1.dotProduct(vp1 - vp2) > epsilon)
|
---|
| 78 | {
|
---|
| 79 | positive = true;
|
---|
| 80 |
|
---|
| 81 | Vector3 n2 = normal.crossProduct((vp1 - vm1).normalise());
|
---|
| 82 | Vector3 n3 = normal.crossProduct((vp2 - vp1).normalise());
|
---|
| 83 |
|
---|
| 84 | for (long a = 0; a < vertexCount; a++)
|
---|
| 85 | {
|
---|
| 86 | if ((a != p1) && (a != p2) && (a != m1) && active.bitSet(a))
|
---|
| 87 | {
|
---|
| 88 | const Point3 v = *vertices[a]->point;
|
---|
| 89 | if (n1.dotProduct((v - vp2).normalise()) > -epsilon && n2.dotProduct((v - vm1).normalise()) > -epsilon && n3.dotProduct((v - vp1).normalise()) > -epsilon)
|
---|
| 90 | {
|
---|
| 91 | positive = false;
|
---|
| 92 | break;
|
---|
| 93 | }
|
---|
| 94 | }
|
---|
| 95 | }
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | n1 = normal.crossProduct((vm2 - vp1).normalise());
|
---|
| 99 | if (n1.dotProduct(vm1 - vp1) > epsilon)
|
---|
| 100 | {
|
---|
| 101 | negative = true;
|
---|
| 102 |
|
---|
| 103 | Vector3 n2 = normal.crossProduct((vm1 - vm2).normalise());
|
---|
| 104 | Vector3 n3 = normal.crossProduct((vp1 - vm1).normalise());
|
---|
| 105 |
|
---|
| 106 | for (long a = 0; a < vertexCount; a++)
|
---|
| 107 | {
|
---|
| 108 | if ((a != m1) && (a != m2) && (a != p1) && active.bitSet(a))
|
---|
| 109 | {
|
---|
| 110 | const Point3 v = *vertices[a]->point;
|
---|
| 111 | if (n1.dotProduct((v - vp1).normalise()) > -epsilon && n2.dotProduct((v - vm2).normalise()) > -epsilon && n3.dotProduct((v - vm1).normalise()) > -epsilon)
|
---|
| 112 | {
|
---|
| 113 | negative = false;
|
---|
| 114 | break;
|
---|
| 115 | }
|
---|
| 116 | }
|
---|
| 117 | }
|
---|
| 118 | }
|
---|
| 119 |
|
---|
| 120 | if ((positive) && (negative))
|
---|
| 121 | {
|
---|
| 122 | float pd = (vp2 - vm1).normalise().dotProduct((vm2 - vm1).normalise());
|
---|
| 123 | float md = (vm2 - vp1).normalise().dotProduct((vp2 - vp1).normalise());
|
---|
| 124 |
|
---|
| 125 | if (fabs(pd - md) < epsilon)
|
---|
| 126 | {
|
---|
| 127 | if (lastPositive) positive = false;
|
---|
| 128 | else negative = false;
|
---|
| 129 | }
|
---|
| 130 | else
|
---|
| 131 | {
|
---|
| 132 | if (pd < md) negative = false;
|
---|
| 133 | else positive = false;
|
---|
| 134 | }
|
---|
| 135 | }
|
---|
| 136 |
|
---|
| 137 | if (positive)
|
---|
| 138 | {
|
---|
| 139 | active.clearBit(p1);
|
---|
| 140 | triangles.push_back(makeTriangle(m1, p1, p2));
|
---|
| 141 |
|
---|
| 142 | p1 = active.getNextSet(p1);
|
---|
| 143 | p2 = active.getNextSet(p2);
|
---|
| 144 |
|
---|
| 145 | lastPositive = true;
|
---|
| 146 | start = -1;
|
---|
| 147 | }
|
---|
| 148 | else if (negative)
|
---|
| 149 | {
|
---|
| 150 | active.clearBit(m1);
|
---|
| 151 | triangles.push_back(makeTriangle(m2, m1, p1));
|
---|
| 152 |
|
---|
| 153 | m1 = active.getPreviousSet(m1);
|
---|
| 154 | m2 = active.getPreviousSet(m2);
|
---|
| 155 |
|
---|
| 156 | lastPositive = false;
|
---|
| 157 | start = -1;
|
---|
| 158 | }
|
---|
| 159 | else
|
---|
| 160 | {
|
---|
| 161 | if (start == -1) start = p2;
|
---|
| 162 | else if (p2 == start) break;
|
---|
| 163 |
|
---|
| 164 | m2 = m1;
|
---|
| 165 | m1 = p1;
|
---|
| 166 | p1 = p2;
|
---|
| 167 | p2 = active.getNextSet(p2);
|
---|
| 168 | }
|
---|
| 169 | }
|
---|
| 170 |
|
---|
| 171 | return triangles;
|
---|
| 172 | }
|
---|