/Users/lyon/j4p/src/bookExamples/ch26Graphics/draw2d/Shapes.java

1    package bookExamples.ch26Graphics.draw2d; 
2     
3     
4    import java.awt.*; 
5    import java.util.Vector; 
6     
7    class Shapes extends Shape { 
8        //ComponentMoveFrame cmf; 
9     
10       // Number of times ray reflects befor fading away 
11       final static int maxCount = 3; 
12    
13       // Refractive index 
14       final static double refIndex = 1.2; 
15    
16       Circle2d closestCircle; 
17    
18    
19       private Vector v = new Vector(); 
20    
21       public void add(Paintable d) { 
22           if (d == null) { 
23               System.out.println("d==null!!"); 
24           } 
25           v.addElement(d); 
26           //cmf.add((Component)d); 
27           //cmf.repaint(); 
28       } 
29    
30       public void paint(Graphics g) { 
31           for (int i = 0; i < v.size(); i++) { 
32               Paintable d = 
33                       (Paintable) v.elementAt(i); 
34               d.paint(g); 
35           } 
36       } 
37    
38       public Line2d getLastLine() { 
39           for (int i = v.size() - 1; i >= 0; i--) 
40               if (v.elementAt(i) instanceof Line2d) 
41                   return 
42                           (Line2d) v.elementAt(i); 
43           return null; 
44       } 
45    
46       public Circle2d getLastCircle() { 
47           for (int i = v.size() - 1; i >= 0; i--) 
48               if (v.elementAt(i) instanceof Circle2d) 
49                   return 
50                           (Circle2d) v.elementAt(i); 
51           return null; 
52       } 
53    
54       public Rect2d getLastRectangle() { 
55           for (int i = v.size() - 1; i >= 0; i--) 
56               if (v.elementAt(i) instanceof Rect2d) 
57                   return 
58                           (Rect2d) v.elementAt(i); 
59           return null; 
60       } 
61    
62       public Vec2d getClosestPoint(Ray2d ray) { 
63           double maxDist = 1000000; 
64           Vec2d closestSoFar = null; 
65    
66           for (int i = v.size() - 1; i >= 0; i--) { 
67               if (!(v.elementAt(i) instanceof Intersects)) 
68                   continue; 
69               Intersects inter = (Intersects) v.elementAt(i); 
70               Vec2d vc = inter.intersect(ray); 
71               if (vc == null) continue; 
72               if (ray.t >= maxDist) continue; 
73               closestSoFar = vc; 
74               if (v.elementAt(i) instanceof Circle2d) { 
75                   closestCircle = (Circle2d) v.elementAt(i); 
76               } else { 
77                   closestCircle = null; 
78               } 
79               maxDist = ray.t; 
80           } 
81           return closestSoFar; 
82       } 
83    
84       public void addLineToLastCircle() { 
85    
86           Ray2d rl; 
87           Ray2d rf; 
88    
89           Line2d l = getLastLine(); 
90           if (l == null) return; 
91           Ray2d r = new Ray2d(l); 
92           addLineToLastCircle(r); 
93       } 
94    
95       public void addLineToLastCircle(Ray2d r) { 
96    
97           Vec2d v = getClosestPoint(r); 
98           if (v == null) return; 
99    
100          if (closestCircle != null) { 
101   
102              Ray2d rl = getReflectRay(closestCircle, v, r.d); 
103              Ray2d rf = getRefractRay(closestCircle, r.p, v, r.d); 
104   
105              rl.p.add(rl.d); 
106              rf.p.add(rf.d); 
107   
108              add(new Line2d(rl.p, rl.vecOnLine(50))); 
109              add(new Line2d(rf.p, rf.vecOnLine(50))); 
110   
111              if (r.count < maxCount) { 
112                  rl.count = r.count + 1; 
113                  addLineToLastCircle(rl); 
114              } 
115              if (r.count < maxCount) { 
116                  rf.count = r.count + 1; 
117                  addLineToLastCircle(rf); 
118              } 
119          } 
120          add(new Line2d(r.p, v)); 
121      } 
122   
123      public Ray2d getReflectRay(Circle2d c, Vec2d p, Vec2d d) { 
124   
125          Vec2d n = new Vec2d(p); 
126          n.sub(c.center); 
127          n.normalize(); 
128   
129          n.mult(2 * d.dot(n)); 
130          d.sub(n); 
131          Ray2d ref = new Ray2d(p, d); 
132          return ref; 
133      } 
134   
135      public Ray2d getRefractRay(Circle2d c, Vec2d o, Vec2d p, Vec2d d) { 
136   
137          double t; 
138          double idx; 
139   
140          Vec2d n = new Vec2d(p); 
141          n.sub(c.center); 
142          n.normalize(); 
143   
144   
145          if (c.inside(o)) { 
146              idx = 1 / refIndex; 
147              n.mult(-1); 
148          } else { 
149              idx = refIndex; 
150          } 
151   
152   
153          t = 1 / d.dot(n); 
154   
155          Vec2d u = new Vec2d(d); 
156          Vec2d v = new Vec2d(n); 
157   
158          u.mult(t); 
159          v.add(u); 
160   
161   
162          t = 1 / ((idx * idx) * u.dot(u) - v.dot(v)); 
163   
164          u.mult(t); 
165          u.sub(n); 
166          n.mult(t); 
167          u.add(n); 
168          u.normalize(); 
169   
170          Ray2d ref = new Ray2d(p, u); 
171          return ref; 
172   
173      } 
174   
175  }