summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Panorama.H10
-rw-r--r--src/Panorama.cxx172
2 files changed, 149 insertions, 33 deletions
diff --git a/src/Panorama.H b/src/Panorama.H
index 3f47b76..3e247d2 100644
--- a/src/Panorama.H
+++ b/src/Panorama.H
@@ -24,6 +24,11 @@
#include "Hill.H"
+typedef enum {
+ PROJECTION_NORMAL = 0,
+ PROJECTION_PANORAMIC = 1
+} Projection_t;
+
class Panorama {
private:
double view_phi, view_lam, view_height;
@@ -37,6 +42,7 @@ class Panorama {
double scale;
double a_nick;
double a_tilt;
+ Projection_t projection;
int get_pos(const char *name, double *phi, double *lam, double *height);
@@ -68,6 +74,10 @@ class Panorama {
double get_value(Hills *p);
+ void set_projection(Projection_t mode);
+
+ Projection_t get_projection();
+
public:
Panorama();
diff --git a/src/Panorama.cxx b/src/Panorama.cxx
index 8def1d9..6113367 100644
--- a/src/Panorama.cxx
+++ b/src/Panorama.cxx
@@ -39,6 +39,14 @@ static int opt_step(double *tan_nick_view,
double tan_dir_m2,
double tan_nick_m2,
double d_m1_2, double d_m2_2, double d_m1_m2_2);
+static int opt_step_panoramic(double *tan_nick_view,
+ double *dir_view,
+ double *n_scale,
+ double dir_m1,
+ double tan_nick_m1,
+ double dir_m2,
+ double tan_nick_m2,
+ double d_m1_2, double d_m2_2, double d_m1_m2_2);
static double
comp_tilt(double tan_nick_view, double tan_dir_view, double n_scale,
@@ -62,6 +70,7 @@ Panorama::Panorama() {
a_tilt = 0.0;
scale = 3500.0;
view_name = NULL;
+ projection = PROJECTION_PANORAMIC;
}
Panorama::~Panorama() {
@@ -269,7 +278,7 @@ Panorama::comp_params(Hill *m1, Hill *m2) {
int
Panorama::optimize(Hill *m1, Hill *m2) {
int i;
- double tan_nick_view, tan_dir_view, n_scale;
+ double tan_nick_view, tan_dir_view, dir_view, n_scale;
double tan_nick_m1, tan_dir_m1;
double tan_nick_m2, tan_dir_m2;
double d_m1_2, d_m2_2, d_m1_m2_2;
@@ -280,6 +289,7 @@ Panorama::optimize(Hill *m1, Hill *m2) {
tan_nick_view = tan(a_nick);
tan_dir_view = tan(a_center);
+ dir_view = a_center;
n_scale = scale;
tan_dir_m1 = tan(m1->alph);
tan_nick_m1 = tan(m1->a_nick);
@@ -290,48 +300,65 @@ Panorama::optimize(Hill *m1, Hill *m2) {
d_m2_2 = pow(x2, 2.0) + pow(y2, 2.0);
d_m1_m2_2 = pow(x1 - x2, 2.0) + pow(y1 - y2, 2.0);
- for (i=0; i<5; i++) {
- opt_step(&tan_nick_view, &tan_dir_view, &n_scale,
+ if (projection == PROJECTION_NORMAL) {
+ for (i=0; i<5; i++) {
+ opt_step(&tan_nick_view, &tan_dir_view, &n_scale,
tan_dir_m1, tan_nick_m1, tan_dir_m2, tan_nick_m2,
d_m1_2, d_m2_2, d_m1_m2_2);
- }
+ }
- if (isnan(tan_dir_view) || isnan(tan_nick_view) ||
- isnan(tan_dir_view) || isnan(n_scale)) {
- fprintf(stderr, "No solution found.\n");
- return 1;
- } else {
+ if (isnan(tan_dir_view) || isnan(tan_nick_view) || isnan(n_scale)) {
+ fprintf(stderr, "No solution found.\n");
+ return 1;
+ }
- a_nick = atan(tan_nick_view);
a_center = atan(tan_dir_view);
- if (a_center > 2.0 * pi_d) {
- a_center = a_center - 2.0 * pi_d;
- } else if (a_center < 0.0) {
- a_center = a_center + 2.0 * pi_d;
+ } else if (projection = PROJECTION_PANORAMIC) {
+
+ for (i=0; i<5; i++) {
+ opt_step_panoramic(&tan_nick_view, &dir_view, &n_scale,
+ m1->alph, tan_nick_m1, m2->alph, tan_nick_m2,
+ d_m1_2, d_m2_2, d_m1_m2_2);
}
- // atan(tan_dir_view) is not the only possible solution.
- // Choose the one which is close to m1->alph.
- if (fabs(a_center - m1->alph) > pi_d/2.0) {
- a_center = a_center + pi_d;
+ if (isnan(dir_view) || isnan(tan_nick_view) || isnan(n_scale)) {
+ fprintf(stderr, "No solution found.\n");
+ return 1;
}
+
+ a_center = dir_view;
+ tan_dir_view = tan(a_center); // needed for tilt computation
+ }
+
+ a_nick = atan(tan_nick_view);
+
+ if (a_center > 2.0 * pi_d) {
+ a_center = a_center - 2.0 * pi_d;
+ } else if (a_center < 0.0) {
+ a_center = a_center + 2.0 * pi_d;
+ }
+
+ // atan(tan_dir_view) is not the only possible solution.
+ // Choose the one which is close to m1->alph.
+ if (fabs(a_center - m1->alph) > pi_d/2.0) {
+ a_center = a_center + pi_d;
+ }
- scale = n_scale;
+ scale = n_scale;
- // use the point with greater distance from center for tilt computation
- if (d_m1_2 > d_m2_2) {
- a_tilt = comp_tilt(tan_nick_view, tan_dir_view, n_scale,
- tan_nick_m1, tan_dir_m1,
- (double) x1, (double) y1);
- } else {
- a_tilt = comp_tilt(tan_nick_view, tan_dir_view, n_scale,
- tan_nick_m2, tan_dir_m2,
- (double) x2, (double) y2);
- }
-
- return 0;
+ // use the point with greater distance from center for tilt computation
+ if (d_m1_2 > d_m2_2) {
+ a_tilt = comp_tilt(tan_nick_view, tan_dir_view, n_scale,
+ tan_nick_m1, tan_dir_m1,
+ (double) x1, (double) y1);
+ } else {
+ a_tilt = comp_tilt(tan_nick_view, tan_dir_view, n_scale,
+ tan_nick_m2, tan_dir_m2,
+ (double) x2, (double) y2);
}
+
+ return 0;
}
void
@@ -382,6 +409,11 @@ Panorama::set_view_height(double v) {
update_angles();
}
+void
+Panorama::set_projection(Projection_t mode) {
+ projection = mode;
+}
+
const char *
Panorama::get_viewpoint() {
return view_name;
@@ -427,6 +459,11 @@ Panorama::get_view_height() {
return view_height;
}
+Projection_t
+Panorama::get_projection() {
+ return projection;
+}
+
int
Panorama::get_pos(const char *name, double *phi, double *lam, double *height) {
int i;
@@ -536,9 +573,14 @@ Panorama::update_coordinates() {
for (i=0; i<visible_mountains->get_num(); i++) {
m = visible_mountains->get(i);
-
- x_tmp = tan(m->a_view) * scale;
+
+ if (projection == PROJECTION_NORMAL) {
+ x_tmp = tan(m->a_view) * scale;
+ } else if (projection == PROJECTION_PANORAMIC) {
+ x_tmp = m->a_view * scale;
+ }
y_tmp = - (tan(m->a_nick - a_nick) * scale);
+
// rotate by a_tilt;
m->x = (int) rint(x_tmp * cos(a_tilt) - y_tmp * sin(a_tilt));
m->y = (int) rint(x_tmp * sin(a_tilt) + y_tmp * cos(a_tilt));
@@ -643,7 +685,30 @@ Panorama::nick(double dist, double height) {
}
+static int
+get_matrix_panoramic(double m[],
+ double tan_nick_view, double dir_view, double scale,
+ double dir_m1, double tan_nick_m1,
+ double dir_m2, double tan_nick_m2) {
+
+
+m[0] = (2.0 * (scale * scale) * (tan_nick_view - tan_nick_m1) * ((tan_nick_m1 * tan_nick_m1) + 1.0) / pow(((tan_nick_m1 * tan_nick_view) + 1.0), 3.0));
+m[1] = (2.0 * (scale * scale) * (dir_m1 - dir_view));
+m[2] = (2.0 * scale * (pow(((tan_nick_view - tan_nick_m1) / ((tan_nick_m1 * tan_nick_view) + 1.0)), 2.0) - pow((dir_view - dir_m1), 2.0)));
+
+m[3] = (2.0 * (scale * scale) * (tan_nick_view - tan_nick_m2) * ((tan_nick_m2 * tan_nick_m2) + 1.0) / pow(((tan_nick_m2 * tan_nick_view) + 1.0), 3.0));
+m[4] = (2.0 * (scale * scale) * (dir_m2 - dir_view));
+m[5] = (2.0 * scale * (pow(((tan_nick_view - tan_nick_m2) / ((tan_nick_m2 * tan_nick_view) + 1.0)), 2.0) - pow((dir_view - dir_m2), 2.0)));
+
+m[6] = (2.0 * (scale * scale) * ((pow(tan_nick_m1, 3.0) * ((2.0 * tan_nick_m2 * (pow(tan_nick_view, 3.0) + tan_nick_view)) + 1.0)) + pow(tan_nick_m2, 3.0) - (pow(tan_nick_view, 4.0) * tan_nick_m2 * pow((tan_nick_m1 - tan_nick_m2), 2.0)) - (2.0 * (tan_nick_m2 * tan_nick_m2) * (tan_nick_view + pow(tan_nick_view, 3.0))) + (tan_nick_m1 * ((2.0 * (pow(tan_nick_view, 3.0) + tan_nick_view) * (pow(tan_nick_m2, 3.0) + (2.0 * tan_nick_m2))) - (pow(tan_nick_view, 4.0) * pow((tan_nick_m1 - tan_nick_m2), 2.0)) - (tan_nick_m2 * tan_nick_m2))) - ((tan_nick_m1 * tan_nick_m1) * ((2.0 * (pow(tan_nick_view, 3.0) + tan_nick_view) * (1.0 + (2.0 * (tan_nick_m2 * tan_nick_m2)))) + tan_nick_m2))) / pow(((1.0 + (tan_nick_m1 * tan_nick_view)) * (1.0 + (tan_nick_view * tan_nick_m2))), 3.0));
+m[7] = 0.0;
+
+m[8] = (-2.0 * scale * (pow(((1.0 + (tan_nick_view * tan_nick_view)) * (tan_nick_m1 - tan_nick_m2) / ((1.0 + (tan_nick_view * tan_nick_m1)) * (1.0 + (tan_nick_view * tan_nick_m2)))), 2.0) + pow((dir_m2 - dir_m1), 2.0)));
+
+
+return 0;
+}
static int
@@ -673,6 +738,47 @@ get_matrix(double m[],
return 0;
}
+static int opt_step_panoramic(double *tan_nick_view,
+ double *dir_view,
+ double *scale,
+ double dir_m1,
+ double tan_nick_m1,
+ double dir_m2,
+ double tan_nick_m2,
+ double d_m1_2, double d_m2_2, double d_m1_m2_2) {
+ double a[9];
+ double b[3];
+ double a_x0[3], f_x0[3], x0[3];
+ int ret;
+
+ get_matrix_panoramic(a, *tan_nick_view, *dir_view, *scale,
+ dir_m1, tan_nick_m1, dir_m2, tan_nick_m2);
+
+ f_x0[0] = d_m1_2 - (pow(((*dir_view - dir_m1) * *scale), 2.0) + pow(((*tan_nick_view - tan_nick_m1) * *scale / ((tan_nick_m1 * *tan_nick_view) + 1.0)), 2.0));
+ f_x0[1] = d_m2_2 - (pow(((*dir_view - dir_m2) * *scale), 2.0) + pow(((*tan_nick_view - tan_nick_m2) * *scale / ((tan_nick_m2 * *tan_nick_view) + 1.0)), 2.0));
+ f_x0[2] = d_m1_m2_2 - (pow((((*tan_nick_view - tan_nick_m2) * *scale / ((tan_nick_m2 * *tan_nick_view) + 1.0)) - ((*tan_nick_view - tan_nick_m1) * *scale / ((tan_nick_m1 * *tan_nick_view) + 1.0))), 2.0) + pow((((*dir_view - dir_m1) * *scale) - ((*dir_view - dir_m2) * *scale)), 2.0));
+
+
+fprintf(stderr, "%f %f %f\n", f_x0[0], f_x0[1], f_x0[2]);
+ x0[0] = *tan_nick_view;
+ x0[1] = *dir_view;
+ x0[2] = *scale;
+
+ rmmult(a_x0, a, x0, 3, 3, 1);
+
+ b[0] = a_x0[0] - f_x0[0];
+ b[1] = a_x0[1] - f_x0[1];
+ b[2] = a_x0[2] - f_x0[2];
+
+ ret = solv(a, b, 3);
+fprintf(stderr, "ret=%d\n", ret);
+ *tan_nick_view = b[0];
+ *dir_view = b[1];
+ *scale = b[2];
+
+ return 0;
+}
+
static int opt_step(double *tan_nick_view,
double *tan_dir_view,