1 /*
2  *
3  * Copyright (C) 2007,2008  Markko Merzin (markko.merzin@ut.ee)
4  *
5  * This file is part of ImageJ plugin Volumest.
6  * 
7  * Volumest plugin is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
20 *****************************************************************************
21 */
22package ee.ut.mrz.volumest;
23
24import ij.measure.Calibration;
25
26/**
27 * Generates new random reper, has methods for translating
28 * point coordinates from cross reper to _this_ reper and
29 * via versa.
30 * @author Markko Merzin, markko.merzin@ut.ee
31 */
32public class Reper {
33
34    private double gridAngle;
35    private double a11;
36    private double a21;
37    private double a12;
38    private double a22;
39    private double c1;
40    private double c2;
41    private double d11;
42    private double d21;
43    private double d12;
44    private double d22;
45    private double f1;
46    private double f2;
47
48    /**
49     * Takes grid witdh in calibration units and Calibration class
50     * from Imagej.
51     * @param gridWitdh Grid witdh in calibration units (in, mm etc.)
52     * @param calibration Class with calibration info from Imagej.
53     */
54    public Reper(double gridWitdh, Calibration calibration) {
55        double pixelsPerUnit = 1 / calibration.pixelWidth;
56        double pixelsPerGridWitdh = pixelsPerUnit * gridWitdh;
57
58        // lets calculate startpoint for new reper
59        this.c1 = Math.random() * pixelsPerGridWitdh;
60        this.c2 = Math.random() * pixelsPerGridWitdh;
61
62        this.gridAngle = ((Math.PI / 2) * Math.random()) - (Math.PI / 4);
63
64        // this.gridAngle = Math.PI / 4;
65
66        // constants for reper recalculations.
67        this.a11 = Math.cos(gridAngle);
68        this.a21 = Math.sin(gridAngle);
69        this.a12 = -Math.sin(gridAngle);
70        this.a22 = Math.cos(gridAngle);
71
72        // constants for afine to cross
73        this.d11 = Math.cos(-gridAngle);
74        this.d21 = Math.sin(-gridAngle);
75        this.d12 = -Math.sin(-gridAngle);
76        this.d22 = Math.cos(-gridAngle);
77
78        double roo;
79        if (Math.abs(this.c1) < 0.000001) {
80            roo = Math.PI / 2;
81        } else {
82            roo = Math.atan(this.c2 / this.c1);
83        }
84
85        double gamma = roo - this.gridAngle;
86
87        double ce = Math.sqrt(Math.pow(this.c1, 2.0) + Math.pow(this.c2, 2.0));
88
89        this.f1 = -1 * ce * Math.cos(gamma);
90        this.f2 = -1 * ce * Math.sin(gamma);
91
92    }
93
94    /**
95     * Translates from cross-reper to afine one. (afine reper is on display).
96     * @param x x coordinate in cross-reper.
97     * @param y y coordinate in cross-reper.
98     * @return x coordinate in afine reper.
99     */
00    public double xFromCrossToAfin(double x, double y) {
01        return a11 * x + a12 * y + c1;
02    }
03
04    /**
05     * Translates from cross-reper to afine one. (afine reper is on display).
06     * @param x x coordinate in cross-reper.
07     * @param y y coordinate in cross-reper.
08     * @return y coordinate in afine reper.
09     */
10    public double yFromCrossToAfin(double x, double y) {
11        return a21 * x + a22 * y + c2;
12    }
13
14    /**
15     * Translates from afine-reper to cross-reper. (afine reper is on display).
16     * @param x x coordinate in afine-reper.
17     * @param y y coordinate in afine-reper.
18     * @return x coordinate in cross reper.
19     */
20    public double xFromAfineToCross(double x, double y) {
21        return d11 * x + d12 * y + f1;
22
23    }
24
25    /**
26     * Translates from afine-reper to cross-reper. (afine reper is on display).
27     * @param x x coordinate in afine-reper.
28     * @param y y coordinate in afine-reper.
29     * @return y coordinate in cross reper.
30     */
31    public double yFromAfineToCross(double x, double y) {
32        return d21 * x + d22 * y + f2;
33    }
34}
35