| Marker.java |
1 package fi.jyu.mit.graphics;
2
3 import java.awt.*;
4
5 /**
6 * Luokka merkkipisteille.
7 * Oliota voi käyttää prototyyppinä luomaan vastaavanlaisia
8 * merkkejä lisää.
9 * <pre>
10 * Käyttö esimerkiksi:
11 * Marker malliMerkki = new Marker(0,0,0.25).setMaxR(5).setType(Marker.CIRCLE);
12 * ...
13 * ikkuna.add(malliMerkki.create(x,y));
14 * </pre>
15 * @author Vesa Lappalainen
16 *
17 */
18 public class Marker extends BasicShape {
19 /**
20 * Rajapinta markkerin piirtämiseksi
21 * @author vesal
22 * @version 19.10.2008
23 */
24 public interface MarkerInterface {
25 /**
26 * Piirtää markerin ruudulle
27 * @param g grafiikkapinta johon piirretään
28 * @param x markerin x-keskipiste skaalattuna kokonaislukuna
29 * @param y markerin y-keskipiste skaalattuna kokonaislukuna
30 * @param r markerin säden skaalattuna kokonaislukuna
31 */
32 public void draw(Graphics g,int x,int y,int r);
33 }
34
35
36 /**
37 * Valmis luokka ympyrämerkkien piirtämistä varten
38 */
39 public static class Circle implements MarkerInterface {
40 /**
41 * @see fi.jyu.mit.graphics.Marker.MarkerInterface#draw(java.awt.Graphics, int, int, int)
42 */
43 @Override
44 public void draw(Graphics g,int x,int y,int r) {
45 g.drawOval(Math.round(x-r), Math.round(y-r), 2*r, 2*r);
46 }
47 }
48
49
50 /**
51 * Valmis luokka Plus-merkkien piirtämistä varten
52 */
53 public static class Plus implements MarkerInterface {
54 /**
55 * @see fi.jyu.mit.graphics.Marker.MarkerInterface#draw(java.awt.Graphics, int, int, int)
56 */
57 @Override
58 public void draw(Graphics g,int x,int y,int r) {
59 g.drawLine(x-r-1, y , x+r+1, y );
60 g.drawLine(x ,y+r+1, x , y-r-1);
61 }
62 }
63
64 /**
65 * Valmis luokka X-merkkien piirtämistä varten
66 */
67 public static class Cross implements MarkerInterface {
68 /**
69 * @see fi.jyu.mit.graphics.Marker.MarkerInterface#draw(java.awt.Graphics, int, int, int)
70 */
71 @Override
72 public void draw(Graphics g,int x,int y,int r) {
73 g.drawLine(x-r-1,y-r-1, x+r+1,y+r+1);
74 g.drawLine(x-r-1,y+r+1, x+r+1,y-r-1);
75 }
76 }
77
78
79 /** Ympyrän piirtävä markkeri */
80 public static final MarkerInterface CIRCLE = new Circle();
81 /** Plussan piirtävä markkeri */
82 public static final MarkerInterface PLUS = new Plus();
83 /** X:n piirtävä piirtävä markkeri */
84 public static final MarkerInterface CROSS = new Cross();
85
86 private MarkerInterface marker = CIRCLE;
87 private final RPoint center;
88 private double r;
89 private int maxR = Integer.MAX_VALUE;
90 private int minR = 1;
91
92 /**
93 * Luo merkkipisteen
94 * @param x merkin keskipisteen x-koordinaatti
95 * @param y merkin keskipisteen y-koordinaatti
96 * @param r ympyrän säde
97 */
98 public Marker(double x, double y, double r) {
99 super();
100 this.center = new RPoint(x, y);
101 this.r = r;
102 initialize();
103 }
104
105 /**
106 * Luo merkkipisteen
107 * @param x merkin keskipisteen x-koordinaatti
108 * @param y merkin keskipisteen y-koordinaatti
109 * @param r ympyrän säde
110 * @param type piirrettävän merkin tyyppi
111 */
112 public Marker(double x, double y, double r, MarkerInterface type) {
113 this(x,y,r);
114 marker = type;
115 }
116
117 /**
118 * Luo uuden ympyrän
119 * @param x ympyrän keskipisteen x-koordinaatti
120 * @param y ympyrän keskipisteen y-koordinaatti
121 * @param z ympyrän keskipisteen z-koordinaatti
122 * @param r ympyrän säde
123 */
124 public Marker(double x, double y, double z, double r) {
125 super();
126 this.center = new RPoint(x, y, z);
127 this.r = r;
128 initialize();
129 }
130
131 /**
132 * Luo uuden ympyrän
133 * @param x ympyrän keskipisteen x-koordinaatti
134 * @param y ympyrän keskipisteen y-koordinaatti
135 * @param z ympyrän keskipisteen z-koordinaatti
136 * @param r ympyrän säde
137 * @param type piirrettävän merkin tyyppi
138 */
139 public Marker(double x, double y, double z, double r, MarkerInterface type) {
140 this(x,y,z,r);
141 marker = type;
142 }
143
144 /**
145 * Alustaa markerin asetukset
146 */
147 private void initialize() {
148 //
149 }
150
151
152 /**
153 * Asetetaan merkille uusi säde. Negatiivinen säde
154 * tarkoittaa määrää pikseleinä. Positiivinen alueen
155 * koordinaatteina.
156 * @param r uusi säteen arvo
157 * @return tämä olio ketjuttamista varten
158 */
159 public Marker setR(double r) {
160 this.r = r;
161 redraw();
162 return this;
163 }
164
165
166 /**
167 * Asetetaan uusi tapa piirtää merkki
168 * @param type merkin piirtäjä
169 * @return tämä olio ketjuttamista varten
170 */
171 public Marker setType(MarkerInterface type) {
172 this.marker = type;
173 redraw();
174 return this;
175 }
176
177 /**
178 * Asetetaan merkin maksimikoko pikseleinä
179 * @param maxR merkin maksimikoko pikseleinä
180 * @return tämä olio ketjuttamista varten
181 */
182 public Marker setMaxR(int maxR) {
183 this.maxR = maxR;
184 redraw();
185 return this;
186 }
187
188
189 /**
190 * Asetetaan merkin maksimikoko pikseleinä
191 * @param minR merkin maksimikoko pikseleinä
192 * @return tämä olio ketjuttamista varten
193 */
194 public Marker setMinR(int minR) {
195 this.minR = minR;
196 redraw();
197 return this;
198 }
199
200
201
202 /**
203 * Piirretään merkki
204 * @see fi.jyu.mit.graphics.BasicShape#drawShape(java.awt.Graphics, fi.jyu.mit.graphics.Matrix)
205 */
206 @Override
207 protected void drawShape(Graphics g, Matrix a) {
208 Vector rp = new Vector(); // NOPMD, luulee vääräksi vektoriksi
209 SPoint sp = new SPoint(0,0);
210 Vector spv = new Vector();
211 double r0;
212 int cx,cy,ri = (int)Math.round(-r);
213 a.transform(center.getX(),center.getY(),center.getZ(),rp,sp);
214 cx = sp.getX();
215 cy = sp.getY();
216 if ( r >= 0 ) {
217 // a.transform(center.getX()-r,center.getY(),center.getZ(),rp,sp);
218 // ri = Math.abs(sp.getX()-cx); // TODO: tämä pyöristyy välillä väärin
219 a.transform(r,0,0,rp,spv); // TODO: ei ota perpektiiviä huomioon
220 r0 = spv.a(0);
221 a.transform(0,0,0,rp,spv);
222 ri = (int) Math.round(Math.abs(r0-spv.a(0)));
223 }
224 if ( ri > maxR ) ri = maxR;
225 if ( ri < minR ) ri = minR;
226 marker.draw(g, cx, cy, ri);
227 }
228
229
230 /**
231 * Metodi joka luo vastaavilla arvoilla olevan merkin
232 * @param x merkin keskipisteen x-koordinaatti
233 * @param y merkin keskipisteen y-koordinaatti
234 * @param z merkin keskipisteen z-koordinaatti
235 * @return uusi merkki
236 */
237 public Marker create(double x, double y, double z) {
238 Marker m = new Marker(x,y,z,r,marker);
239 m.setColor(getColor());
240 m.minR = minR;
241 m.maxR = maxR;
242 return m;
243 }
244
245 /**
246 * Metodi joka luo vastaavilla arvoilla olevan merkin
247 * @param x merkin keskipisteen x-koordinaatti
248 * @param y merkin keskipisteen y-koordinaatti
249 * @return uusi merkki
250 */
251 public Marker create(double x, double y) {
252 return create(x,y,0);
253 }
254
255 }
256