NCBI C Toolkit Cross Reference

C/vibrant/mapping.c


  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 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.