/android/Android(LGame-0.3.2&LAE-1.1)/LGame-0.3.2(OpenGLES)/src/core/org/loon/framework/android/game/core/geom/TriangleBasic.java

http://loon-simple.googlecode.com/ · Java · 297 lines · 205 code · 68 blank · 24 comment · 31 complexity · c61dc861f22b2b5fb149c3e9cb2df4d8 MD5 · raw file

  1. package org.loon.framework.android.game.core.geom;
  2. import java.util.ArrayList;
  3. /**
  4. *
  5. * Copyright 2008 - 2011
  6. *
  7. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  8. * use this file except in compliance with the License. You may obtain a copy of
  9. * the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  15. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  16. * License for the specific language governing permissions and limitations under
  17. * the License.
  18. *
  19. * @project loonframework
  20. * @author chenpeng
  21. * @email??šceponline@yahoo.com.cn
  22. * @version 0.1
  23. */
  24. public class TriangleBasic implements Triangle {
  25. /**
  26. *
  27. */
  28. private static final long serialVersionUID = 1L;
  29. private static final float EPSILON = 0.0000000001f;
  30. private PointList poly = new PointList();
  31. private PointList tris = new PointList();
  32. private boolean tried;
  33. public TriangleBasic() {
  34. }
  35. public void addPolyPoint(float x, float y) {
  36. Point p = new Point(x, y);
  37. if (!poly.contains(p)) {
  38. poly.add(p);
  39. }
  40. }
  41. public int getPolyPointCount() {
  42. return poly.size();
  43. }
  44. public float[] getPolyPoint(int index) {
  45. return new float[] { poly.get(index).x, poly.get(index).y };
  46. }
  47. public boolean triangulate() {
  48. tried = true;
  49. boolean worked = process(poly, tris);
  50. return worked;
  51. }
  52. public int getTriangleCount() {
  53. if (!tried) {
  54. throw new RuntimeException(
  55. "this not Triangle !");
  56. }
  57. return tris.size() / 3;
  58. }
  59. public float[] getTrianglePoint(int t, int i) {
  60. if (!tried) {
  61. throw new RuntimeException(
  62. "this not Triangle !");
  63. }
  64. return tris.get((t * 3) + i).toArray();
  65. }
  66. private float area(PointList contour) {
  67. int n = contour.size();
  68. float sA = 0.0f;
  69. for (int p = n - 1, q = 0; q < n; p = q++) {
  70. Point contourP = contour.get(p);
  71. Point contourQ = contour.get(q);
  72. sA += contourP.getX() * contourQ.getY() - contourQ.getX()
  73. * contourP.getY();
  74. }
  75. return sA * 0.5f;
  76. }
  77. private boolean insideTriangle(float Ax, float Ay, float Bx, float By,
  78. float Cx, float Cy, float Px, float Py) {
  79. float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy;
  80. float cCROSSap, bCROSScp, aCROSSbp;
  81. ax = Cx - Bx;
  82. ay = Cy - By;
  83. bx = Ax - Cx;
  84. by = Ay - Cy;
  85. cx = Bx - Ax;
  86. cy = By - Ay;
  87. apx = Px - Ax;
  88. apy = Py - Ay;
  89. bpx = Px - Bx;
  90. bpy = Py - By;
  91. cpx = Px - Cx;
  92. cpy = Py - Cy;
  93. aCROSSbp = ax * bpy - ay * bpx;
  94. cCROSSap = cx * apy - cy * apx;
  95. bCROSScp = bx * cpy - by * cpx;
  96. return ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f));
  97. }
  98. private boolean snip(PointList contour, int u, int v, int w, int n, int[] V) {
  99. int p;
  100. float Ax, Ay, Bx, By, Cx, Cy, Px, Py;
  101. Ax = contour.get(V[u]).getX();
  102. Ay = contour.get(V[u]).getY();
  103. Bx = contour.get(V[v]).getX();
  104. By = contour.get(V[v]).getY();
  105. Cx = contour.get(V[w]).getX();
  106. Cy = contour.get(V[w]).getY();
  107. if (EPSILON > (((Bx - Ax) * (Cy - Ay)) - ((By - Ay) * (Cx - Ax)))) {
  108. return false;
  109. }
  110. for (p = 0; p < n; p++) {
  111. if ((p == u) || (p == v) || (p == w)) {
  112. continue;
  113. }
  114. Px = contour.get(V[p]).getX();
  115. Py = contour.get(V[p]).getY();
  116. if (insideTriangle(Ax, Ay, Bx, By, Cx, Cy, Px, Py)) {
  117. return false;
  118. }
  119. }
  120. return true;
  121. }
  122. private boolean process(PointList contour, PointList result) {
  123. result.clear();
  124. int n = contour.size();
  125. if (n < 3) {
  126. return false;
  127. }
  128. int[] sV = new int[n];
  129. if (0.0f < area(contour)) {
  130. for (int v = 0; v < n; v++){
  131. sV[v] = v;
  132. }
  133. } else {
  134. for (int v = 0; v < n; v++){
  135. sV[v] = (n - 1) - v;
  136. }
  137. }
  138. int nv = n;
  139. int count = 2 * nv;
  140. for (int m = 0, v = nv - 1; nv > 2;) {
  141. if (0 >= (count--)) {
  142. return false;
  143. }
  144. int u = v;
  145. if (nv <= u) {
  146. u = 0;
  147. }
  148. v = u + 1;
  149. if (nv <= v) {
  150. v = 0;
  151. }
  152. int w = v + 1;
  153. if (nv <= w) {
  154. w = 0;
  155. }
  156. if (snip(contour, u, v, w, nv, sV)) {
  157. int a, b, c, s, t;
  158. a = sV[u];
  159. b = sV[v];
  160. c = sV[w];
  161. result.add(contour.get(a));
  162. result.add(contour.get(b));
  163. result.add(contour.get(c));
  164. m++;
  165. for (s = v, t = v + 1; t < nv; s++, t++) {
  166. sV[s] = sV[t];
  167. }
  168. nv--;
  169. count = 2 * nv;
  170. }
  171. }
  172. return true;
  173. }
  174. private class Point {
  175. private float x;
  176. private float y;
  177. private float[] array;
  178. public Point(float x, float y) {
  179. this.x = x;
  180. this.y = y;
  181. array = new float[] { x, y };
  182. }
  183. public float getX() {
  184. return x;
  185. }
  186. public float getY() {
  187. return y;
  188. }
  189. public float[] toArray() {
  190. return array;
  191. }
  192. public int hashCode() {
  193. return (int) (x * y * 31);
  194. }
  195. public boolean equals(Object other) {
  196. if (other instanceof Point) {
  197. Point p = (Point) other;
  198. return (p.x == x) && (p.y == y);
  199. }
  200. return false;
  201. }
  202. }
  203. private class PointList {
  204. private ArrayList<Point> points = new ArrayList<Point>();
  205. public PointList() {
  206. }
  207. public boolean contains(Point p) {
  208. return points.contains(p);
  209. }
  210. public void add(Point point) {
  211. points.add(point);
  212. }
  213. @SuppressWarnings("unused")
  214. public void remove( Point point) {
  215. points.remove(point);
  216. }
  217. public int size() {
  218. return points.size();
  219. }
  220. public Point get(int i) {
  221. return (Point) points.get(i);
  222. }
  223. public void clear() {
  224. points.clear();
  225. }
  226. }
  227. public void startHole() {
  228. }
  229. }