/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 }