1 package com.insanityengine.ghia.m3;
2
3 /***
4 *
5 * <P>
6 * A 2d line (segment) class using Pt2's
7 * </P>
8 *
9 * <PRE>
10 *
11 * A note on splitting and "front"/"back" assignment:
12 *
13 * Let the Splitting Line be called S
14 * Let the Line being split be called L
15 * Let the normal of S be N, where
16 * S.N.x = +( S.stop.y - S.start.y )
17 * S.N.y = -( S.stop.x - S.start.x )
18 *
19 * Let numerator = N * (L.start - S.start)
20 * Let denominator = -N * (L.end - L.start)
21 * Let t.intersection = numerator/denominator
22 *
23 * If the denominator is 0, the lines are parallel.
24 * If the denominator is is not 0, the lines intersect.
25 *
26 * If the numerator>0, L is in "front" of S; otherwise,
27 * L is in "back" of S.
28 *
29 * If t.intersection is between L's t.min and t.max, then
30 * the line is split. A new Line L2 is created based on
31 * L with t.start=t.intersection and t.stop=L's t.max.
32 * Modify L's t.max to be t.intersection.
33 *
34 * If the numerator>0, L is in "front" of S, and L2 is in
35 * "back" of S; otherwise, L is in "back" of S and L2 is in
36 * "front" of S.
37 *
38 * In terms of generalized binary trees, "front" corresponds to
39 * "left" and "back" corresponds to "right".
40 *
41 * </PRE>
42 *
43 * @author BrianHammond
44 *
45 * $Header: /usr/local/cvsroot/ghia/src/java/com/insanityengine/ghia/m3/Lying.java,v 1.4 2005/03/19 17:50:02 brian Exp $
46 *
47 */
48 public class Lying {
49
50 /***
51 *
52 * Constructor
53 *
54 */
55 public Lying() {
56 }
57
58 /***
59 *
60 * Constructor
61 *
62 */
63 public Lying( Lying other ) {
64 setStart( other.getStart() );
65 setStop( other.getStop() );
66 }
67
68 /***
69 *
70 * Constructor
71 *
72 */
73 public Lying( Pt2 start, Pt2 stop ) {
74 setStart( start );
75 setStop( stop );
76 }
77
78 /***
79 *
80 * Set the value
81 *
82 * @param newValue to use
83 *
84 */
85 public Pt2 getStart() { return start; }
86
87 /***
88 *
89 * Set the value
90 *
91 * @param newValue to use
92 *
93 */
94 public void setStart( Pt2 newValue ) { start.set( newValue ); }
95
96 /***
97 *
98 * Set the value
99 *
100 * @param newValue to use
101 *
102 */
103 public Pt2 getStop() { return stop; }
104
105 /***
106 *
107 * Set the value
108 *
109 * @param newValue to use
110 *
111 */
112 public void setStop( Pt2 newValue ) { stop.set( newValue ); }
113
114 /***
115 *
116 * Set the value
117 *
118 * @param newValue to use
119 *
120 */
121 public Pt2 getNormal() { return normal; }
122
123 /***
124 *
125 * Flip the start and stop pairs
126 *
127 */
128 public void flip() {
129 Pt2 tmp = start;
130 start = stop;
131 stop = start;
132 }
133
134 /***
135 *
136 * Evaluate the normal using the current start
137 * and stop points
138 *
139 * @return the normal
140 *
141 */
142 public Pt2 evalNormal() {
143 diff.set(
144 stop.getX() - start.getX()
145 ,
146 stop.getY() - start.getY()
147 );
148 normal.set( +diff.getY() , -diff.getX() ).normalize();
149 return normal;
150 }
151
152 /***
153 *
154 * Determine when two lines intersect, return the point passed
155 * in or null if no intersection occurs on the segments or cuz
156 * they are parallel
157 *
158 * @param other line
159 * @param hit storage
160 *
161 * @return the point passed if they intersect or null if not
162 *
163 */
164 public Pt2 intersectAt( Lying other, Pt2 hit ) {
165 float t = this.intersect( other );
166 float f = other.intersect( this );
167
168 if ( t < 0 || t > 1 || f < 0 || f > 1 ) {
169 hit = null;
170 } else {
171 hit.set(
172 t * diff.getX()
173 ,
174 t * diff.getY()
175 );
176 }
177 return hit;
178 }
179
180 /***
181 *
182 * When will this line intersect the other line
183 *
184 * @param other line
185 *
186 * @return time of intersection or M3_Constants.bigNumber, if parallel
187 *
188 */
189 public float intersect( Lying other ) {
190 float d = denominator( other );
191 if ( 0 == d ) {
192 d = M3_Constants.bigNumber;
193 } else {
194 d = numerator( other ) / d;
195 }
196 return d;
197 }
198
199 /***
200 *
201 * The numerator = S.N * (L.start - S.start)
202 *
203 * If the numerator>0, L is in "front" of S; otherwise,
204 * L is in "back" of S.
205 *
206 * @param other lying to test
207 *
208 * @return the numerator value
209 *
210 */
211 public float numerator( Lying other ) {
212 return ( float ) (
213 other.getNormal().getX() * ( getStart().getX() - other.getStart().getX() )
214 +
215 other.getNormal().getY() * ( getStart().getY() - other.getStart().getY() )
216 );
217 }
218
219
220 /***
221 *
222 * The denominator = -S.N * (L.end - L.start)
223 *
224 * If the denominator returns 0, then the lines are parallel
225 * otherwise, they intersect
226 *
227 * @param other lying to test
228 *
229 * @return the denominator value
230 *
231 */
232 public float denominator( Lying other ) {
233 return ( float ) (
234 -other.getNormal().getX() * diff.getX()
235 +
236 -other.getNormal().getY() * diff.getY()
237 );
238 };
239
240 /***
241 *
242 * Get the angle from start to stop
243 *
244 * @return the angle from start to stop
245 *
246 */
247 public double getAngle() {
248 return stop.getAngle( start );
249 }
250
251
252
253 private Pt2 start = new Pt2();
254 private Pt2 stop = new Pt2();
255 private Pt2 diff = new Pt2();
256 private Pt2 normal = new Pt2();
257 }
258
259 /***
260 *
261 * $Log: Lying.java,v $
262 * Revision 1.4 2005/03/19 17:50:02 brian
263 * repackaging
264 *
265 * Revision 1.3 2005/02/17 03:31:13 brian
266 * good stuff???
267 *
268 * Revision 1.2 2004/09/27 00:21:12 brian
269 * actually compiles now...
270 *
271 *
272 */