checkpoint
[anneal.git] / src / edu / berkeley / qfat / geom / Plane.java
1 package edu.berkeley.qfat.geom;
2 import javax.media.opengl.*;
3
4 public class Plane implements AffineConstraint {
5
6     // ax+by+cz=d
7     public final float a, b, c, d;
8
9     public Vec norm() { return new Vec(a, b, c); }
10
11     public Plane(Point p, Vec norm) {
12         norm = norm.norm();
13         this.a = norm.x;
14         this.b = norm.y;
15         this.c = norm.z;
16         this.d = p.x*norm.x+p.y*norm.y+p.z*norm.z;
17     }
18
19     /** provided at least one of a,b,c is nonzero, return the Plane representing ax+by+cz=d */
20     public Plane(float a, float b, float c, float d) {
21         this.a = a;
22         this.b = b;
23         this.c = c;
24         this.d = d;
25     }
26
27     public Point intersect(Plane p1, Plane p2) {
28         Vec norm = norm();
29         Plane p3 = this;
30         float z = p1.norm().dot(p2.norm().cross(p3.norm()));
31         if (Math.abs(z) < 0.0001) return null;  // planes do not intersect at a point
32         Vec v1 = p2.norm().cross(p3.norm()).times(-1 * p1.d);
33         Vec v2 = p3.norm().cross(p1.norm()).times(-1 * p2.d);
34         Vec v3 = p1.norm().cross(p2.norm()).times(-1 * p3.d);
35         return Point.ZERO.plus(v1.plus(v2).plus(v3).times(1/z));
36     }
37
38     public Point getProjection(Point p) {
39         throw new RuntimeException("not implemented yet");
40     }
41
42     public AffineConstraint intersect(AffineConstraint c, float epsilon) {
43         if (c instanceof Plane) {
44             Plane p = (Plane)c;
45
46             // same plane
47             if (Math.abs(p.a-this.a) <= epsilon &&
48                 Math.abs(p.b-this.b) <= epsilon &&
49                 Math.abs(p.c-this.c) <= epsilon &&
50                 Math.abs(p.d-this.d) <= epsilon)
51                 return this;
52
53             // parallel planes
54             if (Math.abs(p.norm().cross(norm()).mag()) <= epsilon)
55                 return new AffineConstraint.Nothing();
56
57             Vec u = norm().cross(p.norm());
58             Point point = null;
59             if (Math.abs(u.z) >= Math.abs(u.y) && Math.abs(u.z) >= Math.abs(u.y)) {
60                 point = new Point( (this.b*p.d - p.b*this.d)/(this.a*p.b - p.a*this.b),
61                                    (this.d*p.a - p.d*this.a)/(this.a*p.b - p.a*this.b),
62                                    0);
63             } else if (Math.abs(u.y) >= Math.abs(u.z) && Math.abs(u.y) >= Math.abs(u.x)) {
64                 point = new Point( (this.c*p.d - p.c*this.d)/(this.a*p.c - p.a*this.c),
65                                    0,
66                                    (this.d*p.a - p.d*this.a)/(this.a*p.c - p.a*this.c));
67             } else {
68                 point = new Point( 0,
69                                    (this.c*p.d - p.c*this.d)/(this.b*p.c - p.b*this.c),
70                                    (this.d*p.b - p.d*this.b)/(this.b*p.c - p.b*this.c));
71             }
72
73             return new Line(point, u);
74
75         } else if (c instanceof Line) {
76             Line l = (Line)c;
77             if ( Math.abs(a + b*l.m + this.c*l.n) <= epsilon &&
78                  Math.abs(b * l.c + this.c * l.d + d) <= epsilon)
79                 return l;
80             throw new RuntimeException("not yet implemented");
81
82         } else
83             return c.intersect(this, epsilon);
84     }
85
86     public AffineConstraint multiply(Matrix m) {
87         throw new RuntimeException("not yet implemented");
88     }
89 }