ArViewer  Android Version
Arvos - Augmented reality viewer open source
 All Classes Namespaces Files Functions Variables
Triangle.java
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2012 Gregory Beauchamp
3  *
4  * Derived from
5  * http://android-raypick.blogspot.com/2012/04/first-i-want-to-state-this-is-my-first.html
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of 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,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 package com.mission_base.arviewer_android.viewer.utilities;
21 
22 import java.util.Arrays;
23 
24 
25 public class Triangle
26 {
27  public float[] V0;
28  public float[] V1;
29  public float[] V2;
30 
31  public Triangle(float[] V0, float[] V1, float[] V2)
32  {
33  this.V0 = V0;
34  this.V1 = V1;
35  this.V2 = V2;
36  }
37 
38  private static final float SMALL_NUM = 0.00000001f; // anything that avoids
39  // division overflow
40 
41  // intersectRayAndTriangle(): intersect a ray with a 3D triangle
42  // Input: a ray R, and a triangle T
43  // Output: *I = intersection point (when it exists)
44  // Return: -1 = triangle is degenerate (a segment or point)
45  // 0 = disjoint (no intersect)
46  // 1 = intersect in unique point I1
47  // 2 = are in the same plane
48  public static int intersectRayAndTriangle(Ray R, Triangle T, float[] I)
49  {
50  float[] u, v, n; // triangle vectors
51  float[] dir, w0, w; // ray vectors
52  float r, a, b; // params to calc ray-plane intersect
53 
54  // get triangle edge vectors and plane normal
55  u = Vector.minus(T.V1, T.V0);
56  v = Vector.minus(T.V2, T.V0);
57  n = Vector.crossProduct(u, v); // cross product
58 
59  if (Arrays.equals(n, new float[] { 0.0f, 0.0f, 0.0f }))
60  { // triangle is degenerate
61  return -1; // do not deal with this case
62  }
63  dir = Vector.minus(R.P1, R.P0); // ray direction vector
64  w0 = Vector.minus(R.P0, T.V0);
65  a = -Vector.dot(n, w0);
66  b = Vector.dot(n, dir);
67  if (Math.abs(b) < SMALL_NUM)
68  { // ray is parallel to triangle plane
69  if (a == 0)
70  { // ray lies in triangle plane
71  return 2;
72  }
73  else
74  {
75  return 0; // ray disjoint from plane
76  }
77  }
78 
79  // get intersect point of ray with triangle plane
80  r = a / b;
81  if (r < 0.0f)
82  { // ray goes away from triangle
83  return 0; // => no intersect
84  }
85  // for a segment, also test if (r > 1.0) => no intersect
86 
87  float[] tempI = Vector.addition(R.P0, Vector.scalarProduct(r, dir)); // intersect point of ray and a plane
88 
89  I[0] = tempI[0];
90  I[1] = tempI[1];
91  I[2] = tempI[2];
92 
93  // is I inside T?
94  float uu, uv, vv, wu, wv, D;
95  uu = Vector.dot(u, u);
96  uv = Vector.dot(u, v);
97  vv = Vector.dot(v, v);
98  w = Vector.minus(I, T.V0);
99  wu = Vector.dot(w, u);
100  wv = Vector.dot(w, v);
101  D = (uv * uv) - (uu * vv);
102 
103  // get and test parametric coords
104  float s, t;
105  s = ((uv * wv) - (vv * wu)) / D;
106  if (s < 0.0f || s > 1.0f) // I is outside T
107  return 0;
108  t = (uv * wu - uu * wv) / D;
109  if (t < 0.0f || (s + t) > 1.0f) // I is outside T
110  return 0;
111 
112  return 1; // I is in T
113  }
114 }