|
NCBI Home IEB Home C Toolkit docs C++ Toolkit source browser C Toolkit source browser (2) |
NCBI C Toolkit Cross ReferenceC/vibrant/mapping.c |
source navigation diff markup identifier search freetext search file search |
1 /* mapping.c
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information (NCBI)
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government do not place any restriction on its use or reproduction.
13 * We would, however, appreciate having the NCBI and the author cited in
14 * any work or product based on this material
15 *
16 * Although all reasonable efforts have been taken to ensure the accuracy
17 * and reliability of the software and data, the NLM and the U.S.
18 * Government do not and cannot warrant the performance or results that
19 * may be obtained by using this software or data. The NLM and the U.S.
20 * Government disclaim all warranties, express or implied, including
21 * warranties of performance, merchantability or fitness for any particular
22 * purpose.
23 *
24 * ===========================================================================
25 *
26 * File Name: mapping.c
27 *
28 * Author: Jonathan Kans, Alex Smirnov, Jill Shermer
29 *
30 * Version Creation Date: 1/19/93
31 *
32 * $Revision: 6.4 $
33 *
34 * File Description:
35 *
36 * Modifications:
37 * --------------------------------------------------------------------------
38 * $Log: mapping.c,v $
39 * Revision 6.4 1999/10/04 17:16:31 kans
40 * include ncbidraw.h instead of vibrant.h, a couple Nlm_ prefixes
41 *
42 * Revision 6.3 1999/08/06 19:29:45 vakatov
43 * "NormalizeBox()": bottom >= top!
44 *
45 * Revision 6.2 1999/08/06 18:42:32 vakatov
46 * Moved "NormalizeBox()" from "viewer.c" to "mappingp.[ch]" & made it public
47 *
48 * Revision 6.1 1998/06/12 16:40:24 kans
49 * fixed warnings detected by unix compiler
50 * ==========================================================================
51 */
52
53 #ifndef _NCBIDRAW_
54 #include <ncbidraw.h>
55 #endif
56
57 #ifndef _PICTURE_
58 #include <picture.h>
59 #endif
60
61 #ifndef _PICTUREP_
62 #include <picturep.h>
63 #endif
64
65 #ifndef _MAPPINGP_
66 #include <mappingp.h>
67 #endif
68
69
70 /*****************************************************************************
71 *
72 * LoadBox (box, left, top, right, bottom)
73 * Initializes a box structure with the specified parameters
74 *
75 *****************************************************************************/
76
77 extern void Nlm_LoadBox
78 (Nlm_BoxPtr box, Int4 left, Int4 top, Int4 right, Int4 bottom)
79 {
80 if (box != NULL) {
81 box->left = left;
82 box->top = top;
83 box->right = right;
84 box->bottom = bottom;
85 }
86 }
87
88 extern void Nlm_OutsetBox
89 (Nlm_BoxPtr box, Int4 dX, Int4 dY )
90 {
91 register BoxPtr boxP;
92
93 boxP = box;
94 boxP->left -= dX;
95 boxP->top += dY;
96 boxP->right += dX;
97 boxP->bottom -= dY;
98 }
99
100 /*****************************************************************************
101 *
102 * MapWorldPointToPixel (pt, pnt, scale)
103 * Maps a world coordinates pnt into a viewer coordinates point
104 *
105 *****************************************************************************/
106
107 extern void Nlm_MapWorldPointToPixel
108 (Nlm_PointPtr pt, Nlm_PntPtr pnt, Nlm_ScalePtr scale)
109 {
110 if (pt != NULL && pnt != NULL && scale != NULL) {
111 pt->x = (Nlm_Int2)((scale->offsetX + pnt->x) / scale->scaleX);
112 pt->y = (Nlm_Int2)((scale->offsetY - pnt->y) / scale->scaleY);
113 }
114 }
115
116 /*****************************************************************************
117 *
118 * MapPixelPointToWorld (pnt, pt, scale)
119 * Maps a point in viewer coordinates to a pnt in world coordinates
120 *
121 *****************************************************************************/
122
123 extern void Nlm_MapPixelPointToWorld
124 (Nlm_PntPtr pnt, Nlm_PointPtr pt, Nlm_ScalePtr scale)
125 {
126 if (pnt != NULL && pt != NULL && scale != NULL) {
127 pnt->x = (Int4)pt->x * scale->scaleX - scale->offsetX;
128 pnt->y = scale->offsetY - (Int4)pt->y * scale->scaleY;
129 }
130 }
131
132 extern void Nlm_MapWorldBoxToRect
133 (Nlm_RectPtr r, Nlm_BoxPtr box, Nlm_ScalePtr scale )
134 {
135 Int4 curScale;
136
137 if (r != NULL && box != NULL && scale != NULL) {
138 curScale = scale->scaleX;
139 r->left = (Int2)((scale->offsetX + box->left) / curScale);
140 r->right = (Int2)((scale->offsetX + box->right) / curScale);
141 curScale = scale->scaleY;
142 r->top = (Int2)((scale->offsetY - box->top) / curScale);
143 r->bottom = (Int2)((scale->offsetY - box->bottom) / curScale);
144 }
145 }
146
147 extern void Nlm_MapRectToWorldBox
148 (Nlm_BoxPtr box, Nlm_RectPtr r, Nlm_ScalePtr scale)
149 {
150 Int4 curScale;
151
152 if (r != NULL && box != NULL && scale != NULL) {
153 curScale = scale->scaleX;
154 box->left = (Int4)r->left * scale->scaleX - scale->offsetX;
155 box->right = (Int4)r->right * scale->scaleX - scale->offsetX;
156 curScale = scale->scaleY;
157 box->top = scale->offsetY - (Int4)r->top * scale->scaleY;
158 box->bottom = scale->offsetY - (Int4)r->bottom * scale->scaleY;
159 }
160 }
161
162 /*****************************************************************************
163 *
164 * MapX (pntX, scale)
165 * Maps a horizontal world coordinate to an Int4 in viewer coordinates
166 *
167 *****************************************************************************/
168
169 static Int4 MapX (Int4 pntX, VScalePtr scale)
170 {
171 return (Int4) scale->view.left + (pntX - scale->port.left) / scale->scaleX;
172 }
173
174 /*****************************************************************************
175 *
176 * MapY (pntY, scale)
177 * Maps a vertical world coordinate to an Int4 in viewer coordinates
178 *
179 *****************************************************************************/
180
181 static Int4 MapY (Int4 pntY, VScalePtr scale)
182 {
183 return (Int4)scale->view.bottom - (pntY - scale->port.bottom)/scale->scaleY;
184 }
185
186 /*****************************************************************************
187 *
188 * BoxInViewport (rct, box, scale)
189 * Determines whether a box is visible in the viewport
190 *
191 *****************************************************************************/
192
193 extern Boolean BoxInViewport
194 (Nlm_RectPtr rct, Nlm_BoxPtr box, VScalePtr scale)
195 {
196 if (!box || !scale ||
197 MAX(box->left, scale->port.left) > MIN(box->right, scale->port.right) ||
198 MAX(box->bottom, scale->port.bottom) > MIN(box->top, scale->port.top))
199 return FALSE;
200
201 if ( !rct )
202 return TRUE;
203
204 rct->left = (Int2)
205 MAX (MapX(box->left, scale), (Int4)(scale->view.left - 20));
206 rct->top = (Int2)
207 MAX (MapY(box->top, scale), (Int4)(scale->view.top - 20));
208 rct->right = (Int2)
209 MIN (MapX(box->right, scale), (Int4)(scale->view.right + 20));
210 rct->bottom = (Int2)
211 MIN (MapY(box->bottom, scale), (Int4)(scale->view.bottom + 20));
212 return TRUE;
213 }
214
215
216 /*****************************************************************************
217 *
218 * LineIntoVPort (x1,y1,x2,y2,worldWindow)
219 *
220 *****************************************************************************/
221 extern Boolean LineIntoVPort
222 (Int4Ptr x1, Int4Ptr y1, Int4Ptr x2, Int4Ptr y2, Nlm_BoxPtr worldWindow)
223 {
224 register Int4 ax;
225 register Int4 bx;
226 Int4 xx1,xx2,yy1,yy2;
227 BoxInfo winW;
228 Int2 status1 = 0;
229 Int2 status2 = 0;
230
231 winW = *worldWindow;
232 ax = *x1;
233 xx1 = ax;
234 if ( ax < winW.left ) {
235 status1 = 1;
236 } else if ( ax > winW.right ) {
237 status1 = 2;
238 }
239 ax = *x2;
240 xx2 = ax;
241 if ( ax < winW.left ) {
242 status2 = 1;
243 } else if ( ax > winW.right ) {
244 status2 = 2;
245 }
246 ax = *y1;
247 yy1 = ax;
248 if ( ax < winW.bottom ) { /* 7 6 8 */
249 status1 += 3; /* 1 0 2 */
250 } else if ( ax > winW.top ) { /* 4 3 5 */
251 status1 += 6;
252 }
253 ax = *y2;
254 yy2 = ax;
255 if ( ax < winW.bottom ) {
256 status2 += 3;
257 } else if ( ax > winW.top ) {
258 status2 += 6;
259 }
260 ax = xx1;
261 bx = yy1;
262 switch ( status1 ){
263 case 0:
264 break;
265 case 1:
266 ax = bx + (yy2 - bx) * (winW.left - ax)/(xx2 - ax);
267 if ( (ax < winW.bottom) || (ax > winW.top) ) return FALSE;
268 *y1 = ax;
269 *x1 = winW.left;
270 break;
271 case 2:
272 ax = bx + (yy2 - bx) * (winW.right - ax)/(xx2 - ax);
273 if ( (ax < winW.bottom) || (ax > winW.top) ) return FALSE;
274 *y1 = ax;
275 *x1 = winW.right;
276 break;
277 case 3:
278 ax = ax + (xx2 - ax) * (winW.bottom - bx)/(yy2 - bx);
279 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
280 *x1 = ax;
281 *y1 = winW.bottom;
282 break;
283 case 4:
284 ax = bx + (yy2 - bx) * (winW.left - ax)/(xx2 - ax);
285 if ( (ax < winW.bottom) || (ax > winW.top) ) {
286 ax = xx1;
287 ax = ax + (xx2 - ax) * (winW.bottom - bx)/(yy2 - bx);
288 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
289 *x1 = ax;
290 *y1 = winW.bottom;
291 } else {
292 *y1 = ax;
293 *x1 = winW.left;
294 }
295 break;
296 case 5:
297 ax = bx + (yy2 - bx) * (winW.right - ax)/(xx2 - ax);
298 if ( (ax < winW.bottom) || (ax > winW.top) ) {
299 ax = xx1;
300 ax = ax + (xx2 - ax) * (winW.bottom - bx)/(yy2 - bx);
301 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
302 *x1 = ax;
303 *y1 = winW.bottom;
304 } else {
305 *y1 = ax;
306 *x1 = winW.right;
307 }
308 break;
309 case 6:
310 ax = ax + (xx2 - ax) * (winW.top - bx)/(yy2 - bx);
311 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
312 *x1 = ax;
313 *y1 = winW.top;
314 break;
315 case 7:
316 ax = bx + (yy2 - bx) * (winW.left - ax)/(xx2 - ax);
317 if ( (ax < winW.bottom) || (ax > winW.top) ) {
318 ax = xx1;
319 ax = ax + (xx2 - ax) * (winW.top - bx)/(yy2 - bx);
320 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
321 *x1 = ax;
322 *y1 = winW.top;
323 } else {
324 *y1 = ax;
325 *x1 = winW.left;
326 }
327 break;
328 default:
329 ax = bx + (yy2 - bx) * (winW.right - ax)/(xx2 - ax);
330 if ( (ax < winW.bottom) || (ax > winW.top) ) {
331 ax = xx1;
332 ax = ax + (xx2 - ax) * (winW.top - bx)/(yy2 - bx);
333 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
334 *x1 = ax;
335 *y1 = winW.top;
336 } else {
337 *y1 = ax;
338 *x1 = winW.right;
339 }
340 }
341 ax = xx1;
342 bx = yy1;
343 switch ( status2 ){
344 case 0:
345 break;
346 case 1:
347 ax = bx + (yy2 - bx) * (winW.left - ax)/(xx2 - ax);
348 if ( (ax < winW.bottom) || (ax > winW.top) ) return FALSE;
349 *y2 = ax;
350 *x2 = winW.left;
351 break;
352 case 2:
353 ax = bx + (yy2 - bx) * (winW.right - ax)/(xx2 - ax);
354 if ( (ax < winW.bottom) || (ax > winW.top) ) return FALSE;
355 *y2 = ax;
356 *x2 = winW.right;
357 break;
358 case 3:
359 ax = ax + (xx2 - ax) * (winW.bottom - bx)/(yy2 - bx);
360 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
361 *x2 = ax;
362 *y2 = winW.bottom;
363 break;
364 case 4:
365 ax = bx + (yy2 - bx) * (winW.left - ax)/(xx2 - ax);
366 if ( (ax < winW.bottom) || (ax > winW.top) ) {
367 ax = xx1;
368 ax = ax + (xx2 - ax) * (winW.bottom - bx)/(yy2 - bx);
369 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
370 *x2 = ax;
371 *y2 = winW.bottom;
372 } else {
373 *y2 = ax;
374 *x2 = winW.left;
375 }
376 break;
377 case 5:
378 ax = bx + (yy2 - bx) * (winW.right - ax)/(xx2 - ax);
379 if ( (ax < winW.bottom) || (ax > winW.top) ) {
380 ax = xx1;
381 ax = ax + (xx2 - ax) * (winW.bottom - bx)/(yy2 - bx);
382 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
383 *x2 = ax;
384 *y2 = winW.bottom;
385 } else {
386 *y2 = ax;
387 *x2 = winW.right;
388 }
389 break;
390 case 6:
391 ax = ax + (xx2 - ax) * (winW.top - bx)/(yy2 - bx);
392 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
393 *x2 = ax;
394 *y2 = winW.top;
395 break;
396 case 7:
397 ax = bx + (yy2 - bx) * (winW.left - ax)/(xx2 - ax);
398 if ( (ax < winW.bottom) || (ax > winW.top) ) {
399 ax = xx1;
400 ax = ax + (xx2 - ax) * (winW.top - bx)/(yy2 - bx);
401 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
402 *x2 = ax;
403 *y2 = winW.top;
404 } else {
405 *y2 = ax;
406 *x2 = winW.left;
407 }
408 break;
409 default:
410 ax = bx + (yy2 - bx) * (winW.right - ax)/(xx2 - ax);
411 if ( (ax < winW.bottom) || (ax > winW.top) ) {
412 ax = xx1;
413 ax = ax + (xx2 - ax) * (winW.top - bx)/(yy2 - bx);
414 if ( (ax < winW.left) || (ax > winW.right) ) return FALSE;
415 *x2 = ax;
416 *y2 = winW.top;
417 } else {
418 *y2 = ax;
419 *x2 = winW.right;
420 }
421 }
422 return TRUE;
423 }
424
425 /*****************************************************************************
426 *
427 * IsLineInVPort (x1,y1,x2,y2,worldWindow)
428 *
429 *****************************************************************************/
430 extern Boolean IsLineInVPort
431 (Int4 x1, Int4 y1, Int4 x2, Int4 y2, Nlm_BoxPtr worldWindow)
432 {
433 register Int4 ax;
434 BoxInfo winW;
435 Int2 status1 = 0;
436
437 winW = *worldWindow;
438 ax = x1;
439 if ( ax < winW.left ) {
440 status1 = 1;
441 } else if ( ax > winW.right ) {
442 status1 = 2;
443 }
444 ax = y1; /* 7 6 8 */
445 if ( ax < winW.bottom ) { /* 1 0 2 */
446 status1 += 3; /* 4 3 5 */
447 } else if ( ax > winW.top ) {
448 status1 += 6;
449 }
450 switch ( status1 ) {
451 case 0:
452 return TRUE;
453 case 1:
454 if ( y2 == y1 ) return TRUE;
455 ax = y1 + (y2 - y1) * (winW.left - x1) / (x2 - x1);
456 if ( (ax >= winW.bottom) && (ax <= winW.top) ) return TRUE;
457 break;
458 case 2:
459 if ( y2 == y1 ) return TRUE;
460 ax = y1 + (y2 - y1) * (winW.right - x1) / (x2 - x1);
461 if ( (ax >= winW.bottom) && (ax <= winW.top) ) return TRUE;
462 break;
463 case 3:
464 if ( x2 == x1 ) return TRUE;
465 ax = x1 + (x2 - x1) * (winW.bottom - y1) / (y2 - y1);
466 if ( (ax >= winW.left) && (ax <= winW.right) ) return TRUE;
467 break;
468 case 4:
469 ax = x1 + (x2 - x1) * (winW.bottom - y1) / (y2 - y1);
470 if ( (ax >= winW.left) && (ax <= winW.right) ) return TRUE;
471 ax = y1 + (y2 - y1) * (winW.left - x1) / (x2 - x1);
472 if ( (ax >= winW.bottom) && (ax <= winW.top) ) return TRUE;
473 break;
474 case 5:
475 ax = x1 + (x2 - x1) * (winW.bottom - y1) / (y2 - y1);
476 if ( (ax >= winW.left) && (ax <= winW.right) ) return TRUE;
477 ax = y1 + (y2 - y1) * (winW.right - x1) / (x2 - x1);
478 if ( (ax >= winW.bottom) && (ax <= winW.top) ) return TRUE;
479 break;
480 case 6:
481 if ( x2 == x1 ) return TRUE;
482 ax = x1 + (x2 - x1) * (winW.top - y1) / (y2 - y1);
483 if ( (ax >= winW.left) && (ax <= winW.right) ) return TRUE;
484 break;
485 case 7:
486 ax = y1 + (y2 - y1) * (winW.left - x1) / (x2 - x1);
487 if ( (ax >= winW.bottom) && (ax <= winW.top) ) return TRUE;
488 ax = x1 + (x2 - x1) * (winW.top - y1) / (y2 - y1);
489 if ( (ax >= winW.left) && (ax <= winW.right) ) return TRUE;
490 break;
491 default:
492 ax = x1 + (x2 - x1) * (winW.top - y1) / (y2 - y1);
493 if ( (ax >= winW.left) && (ax <= winW.right) ) return TRUE;
494 ax = y1 + (y2 - y1) * (winW.right - x1) / (x2 - x1);
495 if ( (ax >= winW.bottom) && (ax <= winW.top) ) return TRUE;
496 }
497 return FALSE;
498 }
499
500
501 /*****************************************************************************
502 *
503 * NormalizeBox (box)
504 * Ensures that left <= right and top <= bottom in world coordinates
505 *
506 *****************************************************************************/
507
508 extern void NormalizeBox
509 (Nlm_BoxInfo* box)
510 {
511 Int4 swap;
512 if (box->left > box->right) {
513 swap = box->left;
514 box->left = box->right;
515 box->right = swap;
516 }
517 if (box->top > box->bottom) {
518 swap = box->bottom;
519 box->bottom = box->top;
520 box->top = swap;
521 }
522 }
523
524 |
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more information. |