00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 #include "drawTv_zoom.h"
00048
00049 #if HAVE_CONFIG_H
00050 #include <config.h>
00051 #endif
00052
00053 #include <stdio.h>
00054 #include <math.h>
00055 #include <tina/sys/sysDef.h>
00056 #include <tina/sys/sysPro.h>
00057 #include <tina/math/mathDef.h>
00058 #include <tina/math/mathPro.h>
00059 #include <tina/image/imgGen_region.h>
00060 #include <tinatool/draw/draw_TvDef.h>
00061 #include <tinatool/draw/draw_TvPro.h>
00062
00063 Ipos ipos();
00064 void tv_erase();
00065 void tv_orient2();
00066 void tv_orient3();
00067 void tv_line();
00068 void tv_text();
00069
00070 void tv_shift(Tv * tv, double dx, double dy)
00071 {
00072 tv->cx += (float)dx;
00073 tv->cy += (float)dy;
00074 }
00075
00076 void tv_zoom(Tv * tv, double zoom)
00077 {
00078 double x = (tv->width / 2 - tv->cx) / tv->scalex;
00079 double y = (tv->height / 2 - tv->cy) / tv->scaley;
00080
00081 tv->scalex *= (float)zoom;
00082 tv->scaley *= (float)zoom;
00083 tv->cx = (float)(tv->width / 2 - x * tv->scalex);
00084 tv->cy = (float)(tv->height / 2 - y * tv->scaley);
00085 }
00086
00087 void tv_zoomx(Tv * tv, double zoom)
00088 {
00089 double x = (tv->width / 2 - tv->cx) / tv->scalex;
00090
00091 tv->scalex *= (float)zoom;
00092 tv->cx = (float)(tv->width / 2 - x * tv->scalex);
00093 }
00094
00095 void tv_zoomy(Tv * tv, double zoom)
00096 {
00097 double y = (tv->height / 2 - tv->cy) / tv->scaley;
00098
00099 tv->scaley *= (float)zoom;
00100 tv->cy = (float)(tv->height / 2 - y * tv->scaley);
00101 }
00102
00103 void tv_rot(Tv * tv, double theta)
00104 {
00105 Vec2 down2 = {Vec2_id};
00106 Vec3 down3 = {Vec3_id};
00107
00108 down2 = mat2_vprod(rot2(theta), tv->ey2);
00109 tv_orient2(tv, down2);
00110 down3 = mat3_vprod(rot3(theta, tv->ez3), tv->ey3);
00111 tv_orient3(tv, tv->ez3, down3);
00112 }
00113
00114 void tv_rot2(Tv * tv, double theta)
00115 {
00116 Vec2 down2 = {Vec2_id};
00117
00118 down2 = mat2_vprod(rot2(theta), tv->ey2);
00119 tv_orient2(tv, down2);
00120 }
00121
00122 void tv_rot3(Tv * tv, double theta)
00123 {
00124 Vec2 down2 = {Vec2_id};
00125 Vec3 down3 = {Vec3_id};
00126
00127 down3 = mat3_vprod(rot3(theta, tv->ez3), tv->ey3);
00128 tv_orient3(tv, tv->ez3, down3);
00129 }
00130
00131 void tv_twist(Tv * tv, double theta, Vec3 axis)
00132 {
00133 Mat3 rot = {Mat3_id};
00134 Vec3 aim = {Vec3_id};
00135 Vec3 down = {Vec3_id};
00136
00137 rot = rot3(theta, axis);
00138 aim = mat3_vprod(rot, tv->ez3);
00139 down = mat3_vprod(rot, tv->ey3);
00140 tv_orient3(tv, aim, down);
00141 }
00142
00143 void tv_fly(Tv * tv, Vec3 v, Vec3 down)
00144 {
00145 Vec3 aim = {Vec3_id};
00146
00147 aim = vec3_unit(vec3_sum(tv->ez3, v));
00148 tv_orient3(tv, aim, down);
00149 }
00150
00151 static void centredot(Tv * tv)
00152 {
00153 tv_save_draw(tv);
00154 (void) tv_set_op(tv, rop_copy);
00155 tv_set_color(tv, black);
00156 tv_dot(tv, ipos(tv->width / 2, tv->height / 2));
00157 tv_reset_draw(tv);
00158 }
00159
00160 void tv_imzoom_proc(Tv * tv, int state, Ipos pos)
00161 {
00162 double x, y, dx, dy;
00163 static double oldx, oldy;
00164 static Vec2 p1 = {Vec2_id};
00165 static Vec2 p2 = {Vec2_id};
00166 Imregion roi = {Imregion_id};
00167
00168 x = pos.x;
00169 y = pos.y;
00170 switch (state)
00171 {
00172 case LEFT_DOWN:
00173 case MIDDLE_DOWN:
00174 case RIGHT_DOWN:
00175 tv_set_overlay(tv);
00176 break;
00177 case LEFT_UP:
00178 case MIDDLE_UP:
00179 case RIGHT_UP:
00180 tv_reset_draw(tv);
00181 break;
00182 }
00183
00184
00185 switch (state)
00186 {
00187 case LEFT_DOWN:
00188 oldx = x;
00189 oldy = y;
00190 tv_erase(tv);
00191 centredot(tv);
00192 tv->skeldraw(tv);
00193 break;
00194 case MIDDLE_DOWN:
00195 oldx = x;
00196 oldy = y;
00197 tv_erase(tv);
00198 tv->skeldraw(tv);
00199 break;
00200 case LEFT_DRAG:
00201 tv->skeldraw(tv);
00202 tv_shift(tv, x - oldx, y - oldy);
00203 tv->skeldraw(tv);
00204 oldx = x;
00205 oldy = y;
00206 break;
00207 case MIDDLE_DRAG:
00208 tv->skeldraw(tv);
00209 dx = x - oldx;
00210 dy = y - oldy;
00211 if (fabs(dx) > fabs(dy))
00212 tv_zoom(tv, (1.0 + x) / (1.0 + oldx));
00213 else
00214 tv_rot3(tv,-dy / tv->height);
00215 tv->skeldraw(tv);
00216 oldx = x;
00217 oldy = y;
00218 break;
00219 case RIGHT_DOWN:
00220 p1 = p2 = tv_backproj2(tv, pos);
00221 tv_rect2(tv, p1, p2);
00222 break;
00223 case RIGHT_DRAG:
00224 tv_rect2(tv, p1, p2);
00225 p2 = tv_backproj2(tv, pos);
00226 tv_rect2(tv, p1, p2);
00227 break;
00228 case RIGHT_UP:
00229 tv_rect2(tv, p1, p2);
00230 if (vec2_x(p1) > vec2_x(p2))
00231 SWAP(double, vec2_x(p1), vec2_x(p2));
00232 if (vec2_y(p1) > vec2_y(p2))
00233 SWAP(double, vec2_y(p1), vec2_y(p2));
00234 roi_fill(&roi, (int) vec2_x(p1), (int) vec2_y(p1),
00235 (int) vec2_x(p2), (int) vec2_y(p2));
00236 tv_camera2_roi(tv, &roi);
00237 case LEFT_UP:
00238 case MIDDLE_UP:
00239 tv_free_background(tv);
00240 tv_repaint(tv);
00241 break;
00242 default:
00243 break;
00244 }
00245 }
00246
00247 void tv_zoom2_proc(Tv * tv, int state, Ipos pos)
00248 {
00249 double x, y, dx, dy;
00250 static double oldx, oldy;
00251
00252 x = pos.x;
00253 y = pos.y;
00254 switch (state)
00255 {
00256 case LEFT_DOWN:
00257 case MIDDLE_DOWN:
00258 case RIGHT_DOWN:
00259 tv_set_overlay(tv);
00260 break;
00261 case LEFT_UP:
00262 case MIDDLE_UP:
00263 case RIGHT_UP:
00264 tv_reset_draw(tv);
00265 break;
00266 }
00267 switch (state)
00268 {
00269 case LEFT_DOWN:
00270 oldx = x;
00271 oldy = y;
00272 tv_erase(tv);
00273 centredot(tv);
00274 tv->skeldraw(tv);
00275 break;
00276 case MIDDLE_DOWN:
00277 oldx = x;
00278 oldy = y;
00279 tv_erase(tv);
00280 tv->skeldraw(tv);
00281 break;
00282 case LEFT_DRAG:
00283 tv->skeldraw(tv);
00284 tv_shift(tv, x - oldx, y - oldy);
00285 tv->skeldraw(tv);
00286 oldx = x;
00287 oldy = y;
00288 break;
00289 case MIDDLE_DRAG:
00290 tv->skeldraw(tv);
00291 dx = x - oldx;
00292 dy = y - oldy;
00293 if (fabs(dx) > fabs(dy))
00294 tv_zoom(tv, (1.0 + x) / (1.0 + oldx));
00295 else
00296 tv_rot(tv, -dy / tv->height);
00297 tv->skeldraw(tv);
00298 oldx = x;
00299 oldy = y;
00300 break;
00301 case LEFT_UP:
00302 case MIDDLE_UP:
00303 tv_free_background(tv);
00304 tv_repaint(tv);
00305 break;
00306 default:
00307 break;
00308 }
00309 }
00310
00311 void tv_zoomaf_proc(Tv * tv, int state, Ipos pos)
00312 {
00313 double x, y, dx, dy;
00314 static double oldx, oldy;
00315
00316 x = pos.x;
00317 y = pos.y;
00318 switch (state)
00319 {
00320 case LEFT_DOWN:
00321 case MIDDLE_DOWN:
00322 case RIGHT_DOWN:
00323 tv_set_overlay(tv);
00324 break;
00325 case LEFT_UP:
00326 case MIDDLE_UP:
00327 case RIGHT_UP:
00328 tv_reset_draw(tv);
00329 break;
00330 }
00331 switch (state)
00332 {
00333 case LEFT_DOWN:
00334 oldx = x;
00335 oldy = y;
00336 tv_erase(tv);
00337 centredot(tv);
00338 tv->skeldraw(tv);
00339 break;
00340 case MIDDLE_DOWN:
00341 oldx = x;
00342 oldy = y;
00343 tv_erase(tv);
00344 tv->skeldraw(tv);
00345 break;
00346 case LEFT_DRAG:
00347 tv->skeldraw(tv);
00348 tv_shift(tv, x - oldx, y - oldy);
00349 tv->skeldraw(tv);
00350 oldx = x;
00351 oldy = y;
00352 break;
00353 case MIDDLE_DRAG:
00354 tv->skeldraw(tv);
00355 dx = x - oldx;
00356 dy = y - oldy;
00357 if (fabs(dx) > fabs(dy))
00358 tv_zoomx(tv, (1.0 + x) / (1.0 + oldx));
00359 else
00360 tv_zoomy(tv, (1.0 + y) / (1.0 + oldy));
00361 tv->skeldraw(tv);
00362 oldx = x;
00363 oldy = y;
00364 break;
00365 case LEFT_UP:
00366 case MIDDLE_UP:
00367 tv_free_background(tv);
00368 tv_repaint(tv);
00369 break;
00370 default:
00371 break;
00372 }
00373 }
00374
00375 void tv_zoom3_proc(Tv * tv, int state, Ipos pos)
00376 {
00377 double x, y, dx, dy;
00378 static double oldx, oldy;
00379
00380 x = pos.x;
00381 y = pos.y;
00382 switch (state)
00383 {
00384 case LEFT_DOWN:
00385 case MIDDLE_DOWN:
00386 case RIGHT_DOWN:
00387 tv_set_overlay(tv);
00388 break;
00389 case LEFT_UP:
00390 case MIDDLE_UP:
00391 case RIGHT_UP:
00392 tv_reset_draw(tv);
00393 break;
00394 }
00395 switch (state)
00396 {
00397 case LEFT_DOWN:
00398 oldx = x;
00399 oldy = y;
00400 tv_erase(tv);
00401 centredot(tv);
00402 tv->skeldraw(tv);
00403 break;
00404 case MIDDLE_DOWN:
00405 case RIGHT_DOWN:
00406 oldx = x;
00407 oldy = y;
00408 tv_erase(tv);
00409 tv->skeldraw(tv);
00410 break;
00411 case LEFT_DRAG:
00412 tv->skeldraw(tv);
00413 tv_shift(tv, x - oldx, y - oldy);
00414 tv->skeldraw(tv);
00415 oldx = x;
00416 oldy = y;
00417 break;
00418 case MIDDLE_DRAG:
00419 tv->skeldraw(tv);
00420 dx = x - oldx;
00421 dy = y - oldy;
00422 if (fabs(dx) > fabs(dy))
00423 tv_zoom(tv, (1.0 + x) / (1.0 + oldx));
00424 else
00425 tv_rot(tv, -dy / tv->height);
00426 tv->skeldraw(tv);
00427 oldx = x;
00428 oldy = y;
00429 break;
00430 case RIGHT_DRAG:
00431 tv->skeldraw(tv);
00432 dx = x - oldx;
00433 dy = y - oldy;
00434 if (fabs(dx) > fabs(dy))
00435 {
00436 if (tv->axis_set)
00437 tv_twist(tv, dx / tv->width, tv->axis);
00438 else
00439 tv_twist(tv, dx / tv->width, tv->ey3);
00440 } else
00441 tv_twist(tv, -dy / tv->height, tv->ex3);
00442 tv->skeldraw(tv);
00443 oldx = x;
00444 oldy = y;
00445 break;
00446 case LEFT_UP:
00447 case MIDDLE_UP:
00448 case RIGHT_UP:
00449 tv_free_background(tv);
00450 tv_repaint(tv);
00451 break;
00452 default:
00453 break;
00454 }
00455 }
00456
00457 void tv_zoomgr_proc(Tv * tv, int state, Ipos pos)
00458 {
00459 double x, y, dx, dy;
00460 static double oldx, oldy;
00461
00462 x = pos.x;
00463 y = pos.y;
00464 switch (state)
00465 {
00466 case LEFT_DOWN:
00467 case MIDDLE_DOWN:
00468 case RIGHT_DOWN:
00469 tv_set_overlay(tv);
00470 break;
00471 case LEFT_UP:
00472 case MIDDLE_UP:
00473 case RIGHT_UP:
00474 tv_reset_draw(tv);
00475 break;
00476 }
00477 switch (state)
00478 {
00479 case LEFT_DOWN:
00480 oldx = x;
00481 oldy = y;
00482 tv_erase(tv);
00483 centredot(tv);
00484 tv->skeldraw(tv);
00485 break;
00486 case MIDDLE_DOWN:
00487 case RIGHT_DOWN:
00488 oldx = x;
00489 oldy = y;
00490 tv_erase(tv);
00491 tv->skeldraw(tv);
00492 break;
00493 case LEFT_DRAG:
00494 tv->skeldraw(tv);
00495 tv_shift(tv, x - oldx, y - oldy);
00496 tv->skeldraw(tv);
00497 oldx = x;
00498 oldy = y;
00499 break;
00500 case MIDDLE_DRAG:
00501 tv->skeldraw(tv);
00502 dx = x - oldx;
00503 dy = y - oldy;
00504 if (fabs(dx) > fabs(dy))
00505 tv_zoom(tv, (1.0 + x) / (1.0 + oldx));
00506 tv->skeldraw(tv);
00507 oldx = x;
00508 oldy = y;
00509 break;
00510 case RIGHT_DRAG:
00511 tv->skeldraw(tv);
00512 dx = x - oldx;
00513 dy = y - oldy;
00514 if (fabs(dx) > fabs(dy))
00515 {
00516 Vec3 v = {Vec3_id};
00517
00518 v = vec3_times(dx / tv->width, tv->ex3);
00519 tv_fly(tv, v, tv->axis);
00520 } else
00521 {
00522 Vec3 v = {Vec3_id};
00523
00524 v = vec3_times(dy / tv->height, tv->ey3);
00525 tv_fly(tv, v, tv->axis);
00526 }
00527 tv->skeldraw(tv);
00528 oldx = x;
00529 oldy = y;
00530 break;
00531 case LEFT_UP:
00532 case MIDDLE_UP:
00533 case RIGHT_UP:
00534 tv_free_background(tv);
00535 tv_repaint(tv);
00536 break;
00537 default:
00538 break;
00539 }
00540 }
00541
00542 void tv_zoom_proc(Tv * tv, int state, Ipos pos)
00543 {
00544 switch (tv->zoomlevel)
00545 {
00546 case 0:
00547 return;
00548 case IMZOOM:
00549 tv_imzoom_proc(tv, state, pos);
00550 break;
00551 case ZOOMAF:
00552 tv_zoomaf_proc(tv, state, pos);
00553 break;
00554 case ZOOM2:
00555 tv_zoom2_proc(tv, state, pos);
00556 break;
00557 case ZOOM3:
00558 tv_zoom3_proc(tv, state, pos);
00559 break;
00560 case ZOOMGR:
00561 tv_zoomgr_proc(tv, state, pos);
00562 break;
00563 }
00564 }