diff options
-rw-r--r-- | src/GipfelWidget.H | 5 | ||||
-rw-r--r-- | src/GipfelWidget.cxx | 36 | ||||
-rw-r--r-- | src/Hill.H | 4 | ||||
-rw-r--r-- | src/Hill.cxx | 14 | ||||
-rw-r--r-- | src/Panorama.H | 6 | ||||
-rw-r--r-- | src/Panorama.cxx | 122 | ||||
-rw-r--r-- | src/gipfel.cxx | 10 |
7 files changed, 172 insertions, 25 deletions
diff --git a/src/GipfelWidget.H b/src/GipfelWidget.H index 41c7ce6..575a9d4 100644 --- a/src/GipfelWidget.H +++ b/src/GipfelWidget.H @@ -1,5 +1,5 @@ // -// "$Id: GipfelWidget.H,v 1.11 2005/04/30 09:42:47 hofmann Exp $" +// "$Id: GipfelWidget.H,v 1.12 2005/04/30 21:18:43 hofmann Exp $" // // X11 header file for the Fast Light Tool Kit (FLTK). // @@ -32,6 +32,7 @@ class GipfelWidget : public Fl_Widget { private: Fl_Image *img; Mountain *cur_mountain; + Mountain *marker; Panorama *pan; Fl_Menu_Button *mb; @@ -62,6 +63,8 @@ class GipfelWidget : public Fl_Widget { int comp_params(); + int guess(); + void draw(); }; #endif diff --git a/src/GipfelWidget.cxx b/src/GipfelWidget.cxx index ca4b470..6e93c37 100644 --- a/src/GipfelWidget.cxx +++ b/src/GipfelWidget.cxx @@ -1,5 +1,5 @@ // -// "$Id: GipfelWidget.cxx,v 1.14 2005/04/30 09:42:47 hofmann Exp $" +// "$Id: GipfelWidget.cxx,v 1.15 2005/04/30 21:18:43 hofmann Exp $" // // PSEditWidget routines. // @@ -48,10 +48,16 @@ static Fl_Menu_Item menuitems[] = { }; GipfelWidget::GipfelWidget(int X,int Y,int W, int H): Fl_Widget(X, Y, W, H) { + int i; + img = NULL; pan = new Panorama(); cur_mountain = NULL; mb = NULL; + marker = new Mountain(0,0); + for (i=1; i<=3; i++) { + marker->append(new Mountain(i * 10, 0)); + } fl_register_images(); } @@ -115,6 +121,17 @@ GipfelWidget::draw() { m = m->get_next_visible(); } + + m = marker; + while (m) { + fl_color(FL_GREEN); + + fl_xyline(center_x + m->x + x() - 3, center_y + m->y + y(), center_x + m->x + x() + 3); + fl_yxline(center_x + m->x + x(), center_y + m->y + y() - 3, center_y + m->y + y() + 3); + + m = m->get_next(); + } + fl_pop_clip(); } @@ -133,6 +150,17 @@ GipfelWidget::set_cur_mountain(int m_x, int m_y) { m = m->get_next_visible(); } + m = marker; + while (m) { + if (m_x - center >= m->x - 2 && m_x - center < m->x + 2) { + cur_mountain = m; + redraw(); + return 0; + } + + m = m->get_next(); + } + cur_mountain = NULL; redraw(); return 1; @@ -190,6 +218,12 @@ GipfelWidget::comp_params() { redraw(); } +int +GipfelWidget::guess() { + pan->guess(marker); + redraw(); +} + int GipfelWidget::handle(int event) { @@ -1,5 +1,5 @@ // -// "$Id: Hill.H,v 1.5 2005/04/14 21:15:45 hofmann Exp $" +// "$Id: Hill.H,v 1.6 2005/04/30 21:18:43 hofmann Exp $" // // X11 header file for the Fast Light Tool Kit (FLTK). // @@ -43,6 +43,8 @@ class Mountain { Mountain(const char *n, double p, double l, double h); + Mountain(int x_tmp, int y_tmp); + ~Mountain(); void append(Mountain *m); diff --git a/src/Hill.cxx b/src/Hill.cxx index 2790712..550f925 100644 --- a/src/Hill.cxx +++ b/src/Hill.cxx @@ -1,5 +1,5 @@ // -// "$Id: Hill.cxx,v 1.3 2005/04/13 21:58:31 hofmann Exp $" +// "$Id: Hill.cxx,v 1.4 2005/04/30 21:18:43 hofmann Exp $" // // PSEditWidget routines. // @@ -38,6 +38,18 @@ Mountain::Mountain(const char *n, double p, double l, double h) { next_visible = NULL; } +Mountain::Mountain(int x_tmp, int y_tmp) { + name = ""; + phi = 0.0; + lam = 0.0; + height = 0.0; + alph = 0.0; + x = x_tmp; + y = y_tmp; + next = NULL; + next_visible = NULL; +} + Mountain::~Mountain() { if (next) { delete(next); diff --git a/src/Panorama.H b/src/Panorama.H index e5ff60f..6d60ad1 100644 --- a/src/Panorama.H +++ b/src/Panorama.H @@ -1,5 +1,5 @@ // -// "$Id: Panorama.H,v 1.9 2005/04/30 09:42:47 hofmann Exp $" +// "$Id: Panorama.H,v 1.10 2005/04/30 21:18:43 hofmann Exp $" // // X11 header file for the Fast Light Tool Kit (FLTK). // @@ -61,6 +61,8 @@ class Panorama { int optimize(); + double get_value(Mountain *p); + public: Panorama(); @@ -85,5 +87,7 @@ class Panorama { void set_scale(double s); int comp_params(); + + int guess(Mountain *p1); }; #endif diff --git a/src/Panorama.cxx b/src/Panorama.cxx index 597f6b2..903cd10 100644 --- a/src/Panorama.cxx +++ b/src/Panorama.cxx @@ -1,5 +1,5 @@ // -// "$Id: Panorama.cxx,v 1.17 2005/04/30 17:44:46 hofmann Exp $" +// "$Id: Panorama.cxx,v 1.18 2005/04/30 21:18:43 hofmann Exp $" // // PSEditWidget routines. // @@ -28,6 +28,7 @@ extern "C" { #include <ccmath.h> } + #include "Panorama.H" static int newton(double *tan_nick_view, @@ -152,6 +153,98 @@ Panorama::set_mountain(Mountain *m, int x, int y) { } } +double +Panorama::get_value(Mountain *p) { + Mountain *m; + double v = 0.0, d_min, d; + + if (isnan(scale) || isnan(a_center) || isnan(a_tilt) || isnan(a_nick) || + scale < 1000.0 || scale > 100000.0 || + a_nick > pi_d/4.0 || a_nick < - pi_d/4.0 || + a_tilt > pi_d/4.0 || a_tilt < - pi_d/4.0) { + return 10000000.0; + } + + while (p) { + d_min = 100000.0; + m = visible_mountains; + while (m) { + d = pow(p->x - m->x, 2.0) + pow(p->y - m->y, 2.0); + if (d < d_min) { + d_min = d; + } + + m = m->get_next_visible(); + } + + v = v + d_min; + + p = p->get_next(); + } + + return v; +} + + +int +Panorama::guess(Mountain *p) { + Mountain *p1, *p2, *m_tmp1, *m_tmp2; + double best = 100000000.0, v; + double a_center_best, a_nick_best, a_tilt_best, scale_best; + + p1 = p; + p2 = p->get_next(); + + m_tmp1 = mountains; + while(m_tmp1) { + if (m_tmp1->height / (m_tmp1->dist * EARTH_RADIUS) > + height_dist_ratio) { + m_tmp2 = mountains; + + while(m_tmp2) { + if (m_tmp2->height / (m_tmp2->dist * EARTH_RADIUS) > + height_dist_ratio) { + + if (p1 != p2 && m_tmp1 != m_tmp2) { + + m_tmp1->x = p1->x; + m_tmp1->y = p1->y; + m1 = m_tmp1; + m_tmp2->x = p2->x; + m_tmp2->y = p2->y; + m2 = m_tmp2; + + comp_params(); + + v = get_value(p); + + if (v < best) { + best = v; + a_center_best = a_center; + a_nick_best = a_nick; + a_tilt_best = a_tilt; + scale_best = scale; + fprintf(stderr, "best %f\n", best); + } + } + } + + m_tmp2 = m_tmp2->get_next(); + } + } + m_tmp1 = m_tmp1->get_next(); + } + + a_center = a_center_best; + a_nick = a_nick_best; + a_tilt = a_tilt_best; + scale = scale_best; + fprintf(stderr, "best %f\n", best); + fprintf(stderr, "center = %f, scale = %f, nick=%f\n", a_center /deg2rad, scale, a_nick/deg2rad); + update_visible_mountains(); + return 0; +} + int Panorama::comp_params() { @@ -168,12 +261,10 @@ Panorama::comp_params() { x2 = m2->x; y2 = m2->y; - fprintf(stderr, "center = %f, scale = %f, nick=%f\n", a_center /deg2rad, scale, a_nick/deg2rad); a_center = comp_center_angle(m1->alph, m2->alph, x1, x2); scale = comp_scale(m1->alph, m2->alph, x1, x2); - fprintf(stderr, "center = %f, scale = %f, nick=%f\n", a_center /deg2rad, scale, a_nick/deg2rad); a_nick = atan ((y1 + tan(m1->a_nick) * scale) / ( scale - y1 * tan(m1->a_nick))); - fprintf(stderr, "center = %f, scale = %f, nick=%f\n", a_center /deg2rad, scale, a_nick/deg2rad); + optimize(); @@ -202,13 +293,13 @@ Panorama::optimize() { tan_dir_m2 = tan(m2->alph); tan_nick_m2 = tan(m2->a_nick); - fprintf(stderr, "m1: %d, %d; m2: %d, %d\n", x1, y1, x2, y2); + // fprintf(stderr, "m1: %d, %d; m2: %d, %d\n", x1, y1, x2, y2); d_m1_2 = pow(x1, 2.0) + pow(y1, 2.0); 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); - fprintf(stderr, "d_m1_2 %f, d_m2_2 %f, d_m1_m2_2 %f\n", - d_m1_2, d_m2_2, d_m1_m2_2); + // fprintf(stderr, "d_m1_2 %f, d_m2_2 %f, d_m1_m2_2 %f\n", + // d_m1_2, d_m2_2, d_m1_m2_2); for (i=0; i<8; i++) { newton(&tan_nick_view, &tan_dir_view, &n_scale, @@ -242,11 +333,9 @@ Panorama::optimize() { } - fprintf(stderr, "center = %f, scale = %f, nick=%f tilt %f\n", a_center /deg2rad, scale, a_nick/deg2rad, a_tilt/deg2rad); - - - + return 0; } + void Panorama::set_center_angle(double a) { a_center = a; @@ -328,7 +417,6 @@ Panorama::update_visible_mountains() { m->a_view += 2.0*pi_d; } - // fprintf(stderr, "==> %s %f, dist %f km %f\n", m->name, m->alph, distance(m->phi, m->lam)* 6368, m->a_view); if (m->a_view < pi_d / 2.0 && m->a_view > - pi_d / 2.0) { m->a_nick = nick(m->dist, m->height); x_tmp = tan(m->a_view) * scale; @@ -409,7 +497,7 @@ double Panorama::comp_scale(double a1, double a2, double d1, double d2) { double sign1 = 1.0; double sc, tan_a1, tan_a2; - + tan_a1 = tan(a1); tan_a2 = tan(a2); @@ -491,8 +579,8 @@ static int newton(double *tan_nick_view, f_x0[2] = d_m1_m2_2 - (pow((- (((*tan_dir_view - tan_dir_m1) * *n_scale) / (tan_dir_m1 * *tan_dir_view + 1.0)) + (((*tan_dir_view - tan_dir_m2) * *n_scale) / (tan_dir_m2 * *tan_dir_view + 1))), 2.0) + pow((- (((*tan_nick_view - tan_nick_m1) * *n_scale) / (tan_nick_m1 * *tan_nick_view + 1)) + ((*tan_nick_view - tan_nick_m2) * *n_scale) / (tan_nick_m2 * *tan_nick_view + 1)), 2.0)); - fprintf(stderr, "f_x0[0] %f, f_x0[1] %f, f_x0[2] %f\n", - f_x0[0], f_x0[1], f_x0[2]); + // fprintf(stderr, "f_x0[0] %f, f_x0[1] %f, f_x0[2] %f\n", + // f_x0[0], f_x0[1], f_x0[2]); x0[0] = *tan_nick_view; x0[1] = *tan_dir_view; @@ -505,8 +593,6 @@ static int newton(double *tan_nick_view, b[2] = a_x0[2] - f_x0[2]; ret = solv(a, b, 3); - fprintf(stderr, "solv returned %d\n", ret); - *tan_nick_view = b[0]; *tan_dir_view = b[1]; @@ -534,8 +620,6 @@ comp_tilt(double tan_nick_view, double tan_dir_view, double n_scale, sin_a_tilt2 = - (y * pow(x*x + y*y - y_tmp*y_tmp, 0.5) - x * y_tmp) / (x*x + y*y); - fprintf(stderr, "====> sin_a_tilt1 %f sin_a_tilt2 %f \n", sin_a_tilt1, sin_a_tilt2); - sin_a_tilt = fabs(sin_a_tilt1) < fabs(sin_a_tilt2)?sin_a_tilt1:sin_a_tilt2; res = asin(sin_a_tilt); diff --git a/src/gipfel.cxx b/src/gipfel.cxx index f3dc20d..4539913 100644 --- a/src/gipfel.cxx +++ b/src/gipfel.cxx @@ -1,5 +1,5 @@ // -// "$Id: gipfel.cxx,v 1.14 2005/04/30 09:42:47 hofmann Exp $" +// "$Id: gipfel.cxx,v 1.15 2005/04/30 21:18:43 hofmann Exp $" // // flpsed program. // @@ -90,6 +90,12 @@ void comp_cb(Fl_Widget *, void *) { } } +void guess_cb(Fl_Widget *, void *) { + if (gipf) { + gipf->guess(); + } +} + void about_cb() { fl_message("flpsed -- a pseudo PostScript editor\n" "(c) Johannes Hofmann 2004, 2005\n\n" @@ -207,6 +213,8 @@ int main(int argc, char** argv) { t->align(FL_ALIGN_LEFT); Fl_Button *b = new Fl_Button(200, 60, 20, 15, "comp"); b->callback(comp_cb); + Fl_Button *b1 = new Fl_Button(250, 60, 20, 15, "guess"); + b1->callback(guess_cb); scroll = new Fl_Scroll(0, 75, win->w(), win->h()-75); |