source: src/main/java/agents/anac/y2015/agentBuyogV2/flanagan/io/DigiGraph.java

Last change on this file was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 35.5 KB
Line 
1/*
2* Class DigiGraph
3*
4* Class to digitize a graph presented as a gif, jpg or png
5*
6* WRITTEN BY: Dr Michael Thomas Flanagan
7*
8* DATE: September 2006
9* UPDATE: 8 October 2006, 2 November 2006, 12 May 2008, 5 July 2008, 3 December 2008
10*
11* DOCUMENTATION:
12* See Michael T Flanagan's Java library on-line web pages:
13* http://www.ee.ucl.ac.uk/~mflanaga/java/
14* http://www.ee.ucl.ac.uk/~mflanaga/java/DigiGraph.html
15*
16* Copyright (c) 2006 - 2008
17*
18* PERMISSION TO COPY:
19*
20* Permission to use, copy and modify this software and its documentation for NON-COMMERCIAL purposes is granted, without fee,
21* provided that an acknowledgement to the author, Dr Michael Thomas Flanagan at www.ee.ucl.ac.uk/~mflanaga, appears in all copies
22* and associated documentation or publications.
23*
24* Redistributions of the source code of this source code, or parts of the source codes, must retain the above copyright notice,
25* this list of conditions and the following disclaimer and requires written permission from the Michael Thomas Flanagan:
26*
27* Redistribution in binary form of all or parts of this class must reproduce the above copyright notice, this list of conditions and
28* the following disclaimer in the documentation and/or other materials provided with the distribution and requires written permission
29* from the Michael Thomas Flanagan:
30*
31* Dr Michael Thomas Flanagan makes no representations about the suitability or fitness of the software for any or for a particular purpose.
32* Dr Michael Thomas Flanagan shall not be liable for any damages suffered as a result of using, modifying or distributing this software
33* or its derivatives.
34*
35*****************************************************************************************************************************************************/
36
37package agents.anac.y2015.agentBuyogV2.flanagan.io;
38
39import java.awt.*;
40import java.awt.image.*;
41import java.awt.event.*;
42import java.util.ArrayList;
43import java.io.*;
44import java.net.*;
45import javax.swing.*;
46import javax.swing.JFrame;
47
48import agents.anac.y2015.agentBuyogV2.flanagan.interpolation.CubicSpline;
49import agents.anac.y2015.agentBuyogV2.flanagan.io.*;
50import agents.anac.y2015.agentBuyogV2.flanagan.math.Fmath;
51import agents.anac.y2015.agentBuyogV2.flanagan.plot.PlotGraph;
52
53public class DigiGraph extends Canvas implements MouseListener{
54
55 private Image pic = null; // image containing graph to be digitised
56 private String imagePath = null; // path, i.e. address\name, of the .png, .gif or .jpg containing graph
57 private String imageName = null; // name of the .gif, .png or .jpg file containing graph
58 private String extension = null; // extension of file name, e.g. gif, png or jpg
59
60 private String outputFile = null; // output file (containing digitisation values) name
61 private FileOutput fout = null; // output file (containing digitisation values) reference
62 private int trunc = 16; // number of decimal places in output data
63
64 private String path = "C:"; // path for file selection window
65 private int windowWidth = 0; // width of the window for the graph in pixels
66 private int windowHeight = 0; // height of the window for the graph in pixels
67 private int closeChoice = 1; // =1 clicking on close icon causes window to close
68 // and the the program is exited.
69 // =2 clicking on close icon causes window to close
70 // leaving the program running.
71
72 private int xPos = 0; // mouse x-axis position (in pixels)on last click
73 private int yPos = 0; // mouse y-axis position (in pixels)on last click
74 private int button = 0; // mouse button last clicked
75 // = 0; no button clicked
76 // = 1; left mouse button last clicked
77 // (= 2; middle mouse button last clicked)
78 // = 3; right mouse button last clicked
79 private int sumX = 0; // sum of xPos in calculation of a calibration point
80 private int sumY = 0; // sum of yPos in calculation of a calibration point
81 private int iSum = 0; // number of xPos and yPos in calculation of a calibration point
82 private boolean mouseEntered = false; // = true when mouse enters object
83 // = false when mouse leaves object
84 private double lowYvalue = 0.0; // Y-axis value (entered as double) of the clicked low Y-axis value
85 private double lowYaxisXpixel = 0.0; // X-axis pixel number of the clicked known low Y-axis value
86 private double lowYaxisYpixel = 0.0; // Y-axis pixel number of the clicked known low Y-axis value
87 private double highYvalue = 0.0; // Y-axis value (entered as double) of the clicked high Y-axis value
88 private double highYaxisXpixel = 0.0; // X-axis pixel number of the clicked known high Y-axis value
89 private double highYaxisYpixel = 0.0; // Y-axis pixel number of the clicked known high Y-axis value
90 private double lowXvalue = 0.0; // X-axis value (entered as double) of the clicked low X-axis value
91 private double lowXaxisXpixel = 0.0; // X-axis pixel number of the clicked known low X-axis value
92 private double lowXaxisYpixel = 0.0; // Y-axis pixel number of the clicked known low X-axis value
93 private double highXvalue = 0.0; // X-axis value (entered as double) of the clicked high X-axis value
94 private double highXaxisXpixel = 0.0; // X-axis pixel number of the clicked known high X-axis value
95 private double highXaxisYpixel = 0.0; // Y-axis pixel number of the clicked known high X-axis value
96
97 private ArrayList<Integer> xAndYvalues = new ArrayList<Integer>();
98 // ArrayList holding clicked point xPos and yPos values
99 private int iCounter = 0; // counter for clicks or sum of clicks on first for calibration points
100 private double angleXaxis = 0.0; // clockwise angle from normal of x-axis (degrees)
101 private double angleYaxis = 0.0; // clockwise angle from normal of y-axis (degrees)
102 private double angleMean = 0.0; // mean clockwise angle of axes from normal (degrees)
103 private double angleTolerance = 0.0; // tolerance in above angle before a rotation of all points performed
104 // default option is to rotate if angle is not zero
105 private boolean rotationDone = false; // = false: no rotation of points performed
106 // = true: all points have been rotated
107
108 private double[] xPosPixel = null; // x pixel values converted to double
109 private double[] yPosPixel = null; // y pixel values converted to double
110 private double[] xPositions = null; // Digitized and scaled x values
111 private double[] yPositions = null; // Digitized and scaled y values
112 private int nData = 0; // Number of points digitized (excluding calibration points)
113
114 private int nInterpPoints = 0; // Nnumber of interpolation points
115 private boolean interpOpt = false; // = true if interpolation requested
116 private double[] xInterp = null; // Interpolated x values
117 private double[] yInterp = null; // Interpolated y values
118 private boolean plotOpt = true; // = false if plot of interpolated data not required
119
120 private boolean noIdentical = true; // = true - all identical points stripped to one instance of the identical points
121 // = false - all identical points retained
122
123 private int imageFormat = 0; // = 0 no image file loaded
124 // = 1 GIF format
125 // = 2 JPEG format
126 // = 3 PNG format
127
128 private boolean digitizationDone = false; // = true when digitization complete
129
130 private boolean noYlow = true; // = false when lower y-axis calibration point has been entered
131 private boolean noXlow = true; // = false when lower x-axis calibration point has been entered
132 private boolean noYhigh = true; // = false when higher y-axis calibration point has been entered
133 private boolean noXhigh = true; // = false when higher x-axis calibration point has been entered
134
135 private boolean resize = false; // = true if image is resized
136
137 // Create the window object
138 private JFrame window = new JFrame("Michael T Flanagan's digitizing program - DigiGraph");
139
140 // Constructors
141 // image to be selected from a file select window
142 // window opens on default setting
143 public DigiGraph(){
144 super();
145
146 // Set graph digitizing window size
147 setWindowSize();
148
149 // select image
150 selectImage();
151
152 // set image
153 setImage();
154
155 // Name outputfile
156 outputFileChoice();
157
158 // Add the MouseListener
159 addMouseListener(this);
160 }
161
162 // image to be selected from a file select window
163 // window opens on path (windowPath) provided
164 public DigiGraph(String windowPath){
165 super();
166
167 // Set graph digitizing window size
168 setWindowSize();
169
170 // Set window path
171 this.path = windowPath;
172
173 // select image
174 selectImage();
175
176 // set image
177 setImage();
178
179 // Name outputfile
180 outputFileChoice();
181
182 // Add the MouseListener
183 addMouseListener(this);
184 }
185
186 // Set graph digitizing window size
187 private void setWindowSize(){
188
189 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); // get computer screen size
190 this.windowWidth = screenSize.width - 30; // width of the window for the graph in pixels
191 this.windowHeight = screenSize.height - 40; // height of the window for the graph in pixels
192 }
193
194 // Select graph image
195 private void selectImage(){
196
197 // Identify computer
198 String computerName = null;
199 try{
200 InetAddress localaddress = InetAddress.getLocalHost();
201 computerName = localaddress.getHostName();
202 }
203 catch(UnknownHostException e){
204 System.err.println("Cannot detect local host : " + e);
205 }
206
207 // Set path to file selection window
208 // Replace "name" by your "computer's name" and C:\\DigiGraphDirectory by the path to the directory containing the image to be digitized
209 // Default path is to the C:\ directory or system default directory if no C drive present
210 if(computerName.equals("name"))this.path = "C:\\DigiGraphDirectory";
211
212 // select image file
213 FileChooser fc = new FileChooser(this.path);
214 this.imageName = fc.selectFile();
215 if(!fc.fileFound()){
216 System.out.println("Class DigiGraph: No successful selection of an image file occurred");
217 System.exit(0);
218 }
219 this.imagePath = fc.getPathName();
220
221 int lastDot = this.imagePath.lastIndexOf('.');
222 this.extension = this.imagePath.substring(lastDot+1);
223 if(this.extension.equalsIgnoreCase("gif"))imageFormat=1;
224 if(this.extension.equalsIgnoreCase("jpg"))imageFormat=2;
225 if(this.extension.equalsIgnoreCase("jpeg"))imageFormat=2;
226 if(this.extension.equalsIgnoreCase("jpe"))imageFormat=2;
227 if(this.extension.equalsIgnoreCase("jfif"))imageFormat=2;
228 if(this.extension.equalsIgnoreCase("png"))imageFormat=3;
229 }
230
231 // Set graph image
232 private void setImage(){
233 this.pic = Toolkit.getDefaultToolkit().getImage(this.imagePath);
234 }
235
236 // Name outputfile and set number of decimal placess in the output data
237 private void outputFileChoice(){
238 int posdot = this.imagePath.lastIndexOf('.');
239 this.outputFile = this.imagePath.substring(0, posdot) + "_digitized.txt";
240 this.outputFile = Db.readLine("Enter output file name ", this.outputFile);
241 this.fout = new FileOutput(this.outputFile);
242 this.trunc = Db.readInt("Enter number of decimal places required in output data ", this.trunc);
243 }
244
245 // Reset the number of decimal places in the output data
246 public void setTruncation(int trunc){
247 this.trunc = trunc;
248 }
249
250 // Reset tolerance in axis rotation before applying rotation (degrees)
251 public void setRotationTolerance(double tol){
252 this.angleTolerance = tol;
253 }
254
255 // Reset option of plotting the data
256 // Prevents a plot of the digitized data and the interpolated data, if interpolation optiion chosen,
257 // from being displayed
258 public void noPlot(){
259 this.plotOpt = false;;
260 }
261
262 // Reset path for selection window
263 public void setPath(String path){
264 this.path = path;
265 }
266
267 // Reset height of graph window (pixels)
268 public void setWindowHeight(int windowHeight){
269 this.windowHeight = windowHeight;
270 }
271
272 // Reset width of graph window (pixels)
273 public void setWindowWidth(int windowWidth){
274 this.windowWidth = windowWidth;
275 }
276
277 // Reset close choice
278 public void setCloseChoice(int choice){
279 this.closeChoice = choice;
280 }
281
282 // Reset stripping of identical points option
283 // Keep all identical points
284 public void keepIdenticalPoints(){
285 this.noIdentical = false;
286 }
287
288 // The paint method to display the graph.
289 public void paint(Graphics g){
290
291 // Call graphing method
292 graph(g);
293 }
294
295 // Set up the window, show graph and digitize
296 public void digitize(){
297
298 // Set the initial size of the graph window
299 this.window.setSize(this.windowWidth, this.windowHeight);
300
301 // Set background colour
302 this.window.getContentPane().setBackground(Color.white);
303
304 // Choose close box
305 if(this.closeChoice==1){
306 this.window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
307 }
308 else{
309 this.window.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
310 }
311
312 // Add graph canvas
313 this.window.getContentPane().add("Center", this);
314
315 // Set the window up
316 this.window.pack();
317 this.window.setResizable(true);
318 this.window.toFront();
319
320 // Show the window
321 this.window.setVisible(true);
322 }
323
324
325 // Set up the window, show graph and digitize (alternate spelling)
326 public void digitise(){
327 this.digitize();
328 }
329
330
331 // Display graph and get coordinates
332 private void graph(Graphics g){
333
334 // Display graph to be digitized
335 g.drawImage(this.pic, 10, 30, this);
336 if(!this.resize){
337 g.drawString("RIGHT click anywhere on the screen", 5, 10);
338 int width = this.pic.getWidth(null);
339 int height = this.pic.getHeight(null);
340 System.out.println(width + " xxx " + height);
341 g.drawString(" ", 5, 10);
342 double factor = (double)(windowHeight-30)/(double)height;
343 if((int)(width*factor)>(windowWidth-10))factor = (double)(windowWidth-10)/(double)width;
344 height = (int)((height-30)*factor*0.95);
345 width = (int)((width-10)*factor+0.95);
346 this.pic = this.pic.getScaledInstance(width, height, Image.SCALE_DEFAULT);
347 g.drawImage(this.pic, 10, 30, this);
348 this.resize=true;
349 }
350
351 // Displays cross at pixel coordinates clicked
352 boolean test=true;
353 if(this.xPos==0 && this.yPos==0)test=false;
354 if(test)cursorDoneSign(g, xPos, yPos);
355
356 // Shows action required at top left of window
357 // and opens dialog box to input calibration points
358 if(!this.digitizationDone){
359 switch(this.iCounter){
360 case 0: g.drawString("RIGHT click on lower Y-axis calibration point", 5, 10);
361 break;
362 case 1: if(this.noYlow){
363 this.lowYvalue = Db.readDouble("Enter lower Y-axis calibration value");
364 this.noYlow = false;
365 }
366 g.drawString("RIGHT click on higher Y-axis calibration point", 5, 10);
367 break;
368 case 2: if(this.noYhigh){
369 this.highYvalue = Db.readDouble("Enter higher Y-axis calibration value");
370 this.noYhigh = false;
371 }
372 g.drawString("RIGHT click on lower X-axis calibration point", 5, 10);
373 break;
374 case 3: if(this.noXlow){
375 this.lowXvalue = Db.readDouble("Enter lower X-axis calibration value");
376 this.noXlow = false;
377 }
378 g.drawString("RIGHT click on higher X-axis calibration point", 5, 10);
379 break;
380 case 4: if(this.noXhigh){
381 this.highXvalue = Db.readDouble("Enter higher X-axis calibration value");
382 this.noXhigh = false;
383 }
384 g.drawString("LEFT click on points to be digitized [right click when finished digitizing]", 5, 10);
385 break;
386 default:g.drawString("LEFT click on points to be digitized [right click when finished digitizing]", 5, 10);
387 }
388 }
389 else{
390 g.drawString("You may now close this window", 5, 10);
391 }
392 }
393
394 private void cursorDoneSign(Graphics g, int x, int y){
395 g.drawLine(x-5, y, x+5, y);
396 g.drawLine(x, y-5, x, y+5);
397 g.fillOval(x-3, y-3, 7, 7);
398 }
399
400 // This method will be called when the mouse has been clicked.
401 public void mouseClicked(MouseEvent me) {
402
403 if(!this.digitizationDone){
404 switch(this.iCounter){
405 // Low y-axis calibration point
406 case 0: this.xPos = me.getX();
407 this.yPos = me.getY();
408
409 // identify left (1) or right (3) hand mouse click
410 this.button = me.getButton();
411 // add to sum
412 if(this.button==1){
413 this.sumX += this.xPos;
414 this.sumY += this.yPos;
415 this.iSum++;
416 }
417 else if(this.button==3){
418 this.sumX += this.xPos;
419 this.sumY += this.yPos;
420 this.iSum++;
421 this.lowYaxisXpixel = (double)this.sumX/(double)this.iSum;
422 this.lowYaxisYpixel = (double)this.windowHeight - (double)this.sumY/(double)this.iSum;
423 this.iCounter++;
424 this.sumX = 0;
425 this.sumY = 0;
426 this.iSum = 0;
427 }
428
429 break;
430 // High y-axis calibration point
431 case 1: this.xPos = me.getX();
432 this.yPos = me.getY();
433
434 // identify left (1) or right (3) hand mouse click
435 this.button = me.getButton();
436 // add to sum
437 if(this.button==1){
438 this.sumX += this.xPos;
439 this.sumY += this.yPos;
440 this.iSum++;
441 }
442 else if(this.button==3){
443 this.sumX += this.xPos;
444 this.sumY += this.yPos;
445 this.iSum++;
446 this.highYaxisXpixel = (double)this.sumX/(double)this.iSum;
447 this.highYaxisYpixel = (double)this.windowHeight - (double)this.sumY/(double)this.iSum;
448 this.iCounter++;
449 this.sumX = 0;
450 this.sumY = 0;
451 this.iSum = 0;
452 }
453 break;
454 // Low x-axis calibration point
455 case 2: this.xPos = me.getX();
456 this.yPos = me.getY();
457
458 // identify left (1) or right (3) hand mouse click
459 this.button = me.getButton();
460 // add to sum
461 if(this.button==1){
462 this.sumX += this.xPos;
463 this.sumY += this.yPos;
464 this.iSum++;
465 }
466 else if(this.button==3){
467 this.sumX += this.xPos;
468 this.sumY += this.yPos;
469 this.iSum++;
470 this.lowXaxisXpixel = (double)this.sumX/(double)this.iSum;
471 this.lowXaxisYpixel = (double)this.windowHeight - (double)this.sumY/(double)this.iSum;
472 this.iCounter++;
473 this.sumX = 0;
474 this.sumY = 0;
475 this.iSum = 0;
476 }
477 break;
478 // High x-axis calibration point
479 case 3: this.xPos = me.getX();
480 this.yPos = me.getY();
481
482 // identify left (1) or right (3) hand mouse click
483 this.button = me.getButton();
484 // add to sum
485
486 PixelGrabber pixelGrabber=new PixelGrabber(pic, this.xPos, this.yPos, 1, 1, false);
487
488 if(this.button==1){
489 this.sumX += this.xPos;
490 this.sumY += this.yPos;
491 this.iSum++;
492 }
493 else if(this.button==3){
494 this.sumX += this.xPos;
495 this.sumY += this.yPos;
496 this.iSum++;
497 this.highXaxisXpixel = (double)this.sumX/(double)this.iSum;
498 this.highXaxisYpixel = (double)this.windowHeight - (double)this.sumY/(double)this.iSum;
499 this.iCounter++;
500 this.sumX = 0;
501 this.sumY = 0;
502 this.iSum = 0;
503 }
504 break;
505 // Data points
506 default:
507 this.xPos = me.getX();
508 this.yPos = me.getY();
509
510 // identify left (1) or right (3) hand mouse click
511 this.button = me.getButton();
512 if(this.button==1){
513 this.xAndYvalues.add(new Integer(this.xPos));
514 this.xAndYvalues.add(new Integer(this.yPos));
515 }
516
517 // close file if right button clicked
518 if(this.button==3 && this.xAndYvalues.size()/2!=0){
519 this.outputData();
520 this.digitizationDone = true;
521 }
522 }
523 }
524
525 //show the results of the click
526 repaint();
527 }
528
529 // Output data to file and to graph
530 private void outputData(){
531
532 // dimension arrays
533 this.nData = this.xAndYvalues.size()/2;
534 System.out.println("nData " + this.nData);
535 this.xPositions = new double[this.nData];
536 this.yPositions = new double[this.nData];
537 this.xPosPixel = new double[this.nData];
538 this.yPosPixel = new double[this.nData];
539
540 int ii = 0;
541 // Convert pixel values to doubles
542 for(int i=0; i<this.nData; i++){
543 int xx = this.xAndYvalues.get(ii);
544 ii++;
545 int yy = this.xAndYvalues.get(ii);
546 ii++;
547 this.xPosPixel[i] = (double)xx;
548 this.yPosPixel[i] = (double)this.windowHeight - (double)yy;
549 }
550
551 // Check if graph axes are to be rotated and, if so, rotate
552 this.checkForRotation();
553
554 // Scale the pixel values to true values
555 for(int i=0; i<this.nData; i++){
556 this.xPositions[i] = this.lowXvalue + (this.xPosPixel[i] - this.lowXaxisXpixel)*(this.highXvalue - this.lowXvalue)/(this.highXaxisXpixel - this.lowXaxisXpixel);
557 this.yPositions[i] = this.lowYvalue + (this.yPosPixel[i] - this.lowYaxisYpixel)*(this.highYvalue - this.lowYvalue)/(this.highYaxisYpixel - this.lowYaxisYpixel);
558 }
559
560 // Check for identical points and remove one of all pairs of such points
561 if(this.noIdentical)this.checkForIdenticalPoints();
562
563 // Request to increase number of data points using a cubic spline interpolation
564 String message = "Do you wish to increase number of data points\n";
565 message += "using cubic spline interpolation?";
566 boolean opt = Db.noYes(message);
567 if(opt){
568 this.nInterpPoints = Db.readInt("Enter number of interpolation points", 200);
569 interpolation();
570 this.interpOpt = true;
571 }
572 else{
573 if(plotOpt)plotDigitisedPoints();
574 }
575
576 // Output digitized data
577 this.fout.println("Digitization output for DigiGraph class (M. T. Flanagan Java Library)");
578 this.fout.println();
579 this.fout.dateAndTimeln();
580 this.fout.println();
581 this.fout.println("Image used in the digitization: " + this.imageName);
582 this.fout.println("Location of the image used in the digitization: " + this.imagePath);
583 this.fout.println();
584 this.fout.println("X-axis skew angle " + Fmath.truncate(this.angleXaxis, 4) + " degrees");
585 this.fout.println("Y-axis skew angle " + Fmath.truncate(this.angleYaxis, 4) + " degrees");
586 this.fout.println("Axes mean skew angle " + Fmath.truncate(this.angleMean, 4) + " degrees");
587 if(this.rotationDone){
588 this.fout.println("Axes and all points rotated to bring axes to normal position");
589 }
590 else{
591 this.fout.println("No rotation of axes or points performed");
592 }
593 this.fout.println();
594 this.fout.println("Number of digitized points: " + this.nData);
595 this.fout.println();
596 this.fout.printtab("X-value");
597 this.fout.println("Y-value");
598
599 for(int i=0; i<this.nData; i++){
600 this.fout.printtab(Fmath.truncate(this.xPositions[i], trunc));
601 this.fout.println(Fmath.truncate(this.yPositions[i], trunc));
602 }
603 this.fout.println();
604
605 // Output interpolated data if calculated
606 if(this.interpOpt){
607 this.fout.println();
608 this.fout.println("Interpolated data (cubic spline)");
609 this.fout.println();
610 this.fout.println("Number of interpolated points: " + this.nInterpPoints);
611 this.fout.println();
612 this.fout.printtab("X-value");
613 this.fout.println("Y-value");
614 for(int i=0; i<this.nInterpPoints; i++){
615 this.fout.printtab(Fmath.truncate(this.xInterp[i], trunc));
616 this.fout.println(Fmath.truncate(this.yInterp[i], trunc));
617 }
618 }
619
620 this.fout.close();
621 }
622
623 // Check for axes rotation
624 private void checkForRotation(){
625 double tangent = (this.highYaxisXpixel - this.lowYaxisXpixel)/(this.highYaxisYpixel - this.lowYaxisYpixel);
626 this.angleYaxis = Math.toDegrees(Math.atan(tangent));
627 tangent = (this.lowXaxisYpixel - this.highXaxisYpixel)/(this.highXaxisXpixel - this.lowXaxisXpixel);
628 this.angleXaxis = Math.toDegrees(Math.atan(tangent));
629 this.angleMean = (this.angleXaxis + this.angleYaxis)/2.0;
630 double absMean = Math.abs(this.angleMean);
631 if(absMean!=0.0 && absMean>this.angleTolerance)performRotation();
632 }
633
634 // Rotate axes and all points
635 private void performRotation(){
636 // Find pixel zero-zero origin
637 double tangentX = (this.highXaxisYpixel - this.lowXaxisYpixel)/(this.highXaxisXpixel - this.lowXaxisXpixel);
638 double interceptX = this.highXaxisYpixel - tangentX*this.highXaxisXpixel;
639 double tangentY = (this.highYaxisYpixel - this.lowYaxisYpixel)/(this.highYaxisXpixel - this.lowYaxisXpixel);
640 double interceptY = this.highYaxisYpixel - tangentY*this.highYaxisXpixel;
641 double originX = (interceptX - interceptY)/(tangentY - tangentX);
642 double originY = tangentY*originX + interceptY;
643
644 // Rotate axes calibration points
645 double angleMeanRad = Math.toRadians(this.angleMean);
646 double cosphi = Math.cos(-angleMeanRad);
647 double sinphi = Math.sin(-angleMeanRad);
648 double highXaxisXpixelR = (this.highXaxisXpixel-originX)*cosphi + (this.highXaxisYpixel-originY)*sinphi + originX;
649 double highXaxisYpixelR = -(this.highXaxisXpixel-originX)*sinphi + (this.highXaxisYpixel-originY)*cosphi + originY;
650 double lowXaxisXpixelR = (this.lowXaxisXpixel-originX)*cosphi + (this.lowXaxisYpixel-originY)*sinphi + originX;
651 double lowXaxisYpixelR = -(this.lowXaxisXpixel-originX)*sinphi + (this.lowXaxisYpixel-originY)*cosphi + originY;
652 double highYaxisXpixelR = (this.highYaxisXpixel-originX)*cosphi + (this.highYaxisYpixel-originY)*sinphi + originX;
653 double highYaxisYpixelR = -(this.highYaxisXpixel-originX)*sinphi + (this.highYaxisYpixel-originY)*cosphi + originY;
654 double lowYaxisXpixelR = -(this.lowYaxisXpixel-originX)*cosphi + (this.lowYaxisYpixel-originY)*sinphi + originX;
655 double lowYaxisYpixelR = (this.lowYaxisXpixel-originX)*sinphi + (this.lowYaxisYpixel-originY)*cosphi + originY;
656
657 this.highXaxisXpixel = highXaxisXpixelR;
658 this.highXaxisYpixel = highXaxisYpixelR;
659 this.lowXaxisXpixel = lowXaxisXpixelR;
660 this.lowXaxisYpixel = lowXaxisYpixelR;
661 this.highYaxisXpixel = highYaxisXpixelR;
662 this.highYaxisYpixel = highYaxisYpixelR;
663 this.lowYaxisXpixel = lowYaxisXpixelR;
664 this.lowYaxisYpixel = lowYaxisYpixelR;
665
666 // Rotate data points
667 for(int i=0; i<this.nData; i++){
668 double xx = (this.xPosPixel[i]-originX)*cosphi + (this.yPosPixel[i]-originY)*sinphi + originX;
669 double yy = -(this.xPosPixel[i]-originX)*sinphi + (this.yPosPixel[i]-originY)*cosphi + originY;
670 this.xPosPixel[i] = xx;
671 this.yPosPixel[i] = yy;
672 }
673
674 this.rotationDone = true;
675 }
676
677 // This is called when the mouse has been pressed
678 // since it is empty nothing happens here.
679 public void mousePressed (MouseEvent me) {}
680
681 // This is called when the mouse has been released
682 // since it is empty nothing happens here.
683 public void mouseReleased (MouseEvent me) {}
684
685 // This is executed when the mouse enters the object.
686 // It will only be executed again when the mouse has left and then re-entered.
687 public void mouseEntered (MouseEvent me) {
688 this.mouseEntered = true;
689 repaint();
690 }
691
692 // This is executed when the mouse leaves the object.
693 public void mouseExited (MouseEvent me) {
694 this.mouseEntered = false;
695 repaint();
696 }
697
698 // Performs a cubic spline interpolation on the digitized points
699 private void interpolation(){
700 // Dimension interpolation arrasys
701 this.xInterp = new double[this.nInterpPoints];
702 this.yInterp = new double[this.nInterpPoints];
703
704 // Calculate x-axis interpolation points
705 double incr = (this.xPositions[this.nData-1] - this.xPositions[0])/(this.nInterpPoints - 1);
706 this.xInterp[0] = this.xPositions[0];
707 for(int i=1; i<this.nInterpPoints-1; i++){
708 this.xInterp[i] = this.xInterp[i-1] + incr;
709 }
710 this.xInterp[this.nInterpPoints-1] = this.xPositions[this.nData-1];
711
712 CubicSpline cs = new CubicSpline(this.xPositions, this.yPositions);
713
714 // Interpolate y values
715 for(int i=0; i<this.nInterpPoints; i++)this.yInterp[i] = cs.interpolate(this.xInterp[i]);
716
717 // Plot interpolated curve
718 if(this.plotOpt){
719 int nMax = Math.max(this.nInterpPoints, this.nData);
720 double[][] plotData = PlotGraph.data(2, nMax);
721
722 plotData[0] = this.xPositions;
723 plotData[1] = this.yPositions;
724 plotData[2] = this.xInterp;
725 plotData[3] = this.yInterp;
726
727 PlotGraph pg = new PlotGraph(plotData);
728
729 pg.setGraphTitle("Cubic Spline Interpolation of Digitised Points");
730 pg.setGraphTitle2(this.imagePath);
731
732 pg.setXaxisLegend("x");
733 pg.setYaxisLegend("y");
734
735 int[] lineOpt = {0, 3};
736 pg.setLine(lineOpt);
737 int[] pointOpt = {4, 0};
738 pg.setPoint(pointOpt);
739
740 pg.plot();
741
742 }
743 }
744
745 // Checks for and removes all but one of identical points
746 public void checkForIdenticalPoints(){
747 int nP = this.nData;
748 boolean test1 = true;
749 int ii = 0;
750 while(test1){
751 boolean test2 = true;
752 int jj = ii+1;
753 while(test2){
754 System.out.println("ii " + ii + " jj " + jj);
755 if(this.xPositions[ii]==this.xPositions[jj] && this.yPositions[ii]==this.yPositions[jj]){
756 System.out.print("Class DigiGraph: two identical points, " + this.xPositions[ii] + ", " + this.yPositions[ii]);
757 System.out.println(", in data array at indices " + ii + " and " + jj + ", one point removed");
758
759 for(int i=jj; i<nP; i++){
760 this.xPositions[i-1] = this.xPositions[i];
761 this.yPositions[i-1] = this.yPositions[i];
762 }
763 nP--;
764 if((nP-1)==ii)test2 = false;
765 }
766 else{
767 jj++;
768 if(jj>=nP)test2 = false;
769 }
770 }
771 ii++;
772 if(ii>=nP-1)test1 = false;
773 }
774
775 // Repack arrays if points deleted
776 if(nP!=this.nData){
777 double[] holdX = new double[nP];
778 double[] holdY = new double[nP];
779 for(int i=0; i<nP; i++){
780 holdX[i] = this.xPositions[i];
781 holdY[i] = this.yPositions[i];
782 }
783 this.xPositions = holdX;
784 this.yPositions = holdY;
785 this.nData = nP;
786 }
787 }
788
789 // Plots the digitized points
790 private void plotDigitisedPoints(){
791
792 // Plot interpolated curve
793 double[][] plotData = PlotGraph.data(1, this.nData);
794
795 plotData[0] = this.xPositions;
796 plotData[1] = this.yPositions;
797
798 PlotGraph pg = new PlotGraph(plotData);
799
800 pg.setGraphTitle("Plot of the Digitised Points");
801 pg.setGraphTitle2(this.imagePath);
802
803 pg.setXaxisLegend("x");
804 pg.setYaxisLegend("y");
805
806 int[] lineOpt = {0};
807 pg.setLine(lineOpt);
808 int[] pointOpt = {4};
809 pg.setPoint(pointOpt);
810
811 pg.plot();
812 }
813}
814
815
816
Note: See TracBrowser for help on using the repository browser.