NCBI C Toolkit Cross Reference

C/vibrant/prim3d3.c


  1 /*   prim3d3.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:  prim3d3.c
 27 *
 28 * Author:  Alex Smirnov
 29 *
 30 * Version Creation Date:   04/03/95
 31 *
 32 * $Revision: 6.1 $
 33 *
 34 * File Description: 
 35 *
 36 * Modifications:  
 37 * --------------------------------------------------------------------------
 38 * Date     Name        Description of modification
 39 * -------  ----------  -----------------------------------------------------
 40 *
 41 *
 42 * ==========================================================================
 43 */
 44 
 45 #ifndef _VIBRANT_
 46 #include <vibrant.h>
 47 #endif
 48 
 49 #ifndef _PPICT3D_
 50 #include <ppict3d.h>
 51 #endif
 52 
 53 #ifndef _PDIAGNOS_
 54 #include <pdiagnos.h>
 55 #endif
 56 
 57 /*****************************************************************************
 58 *
 59 *   DEFINES
 60 *
 61 *****************************************************************************/
 62 #define SETARCPIXEL(zptr,imageptr,z) \
 63 {long offset; \
 64  long y_cur; long x_cur; \
 65  long reg1_save; long reg1_save_save; long zptr_save; long im_save; \
 66  if ( needChk){ \
 67    if ( (arcBMinX <= arc_xmax) && (arcBMaxX >= arc_xmin) && \
 68         (arcBMinY <= arc_ymax) && (arcBMaxY >= arc_ymin) ) { \
 69      if ( (arcBMinX > arc_xmin) && (arcBMaxX < arc_xmax) && \
 70           (arcBMinY > arc_ymin) && (arcBMaxY < arc_ymax) ) { \
 71        reg1_save = reg1; \
 72        reg1 = (Nlm_stCon.zmaxPersp1-z); \
 73        im_save = imageptr; \
 74        imageptr = arcBTotal; \
 75        while ( imageptr > 0 ){ \
 76          imageptr--; \
 77          zptr_save = zptr; \
 78          offset = (arcBufferY[imageptr]/reg1) * Nlm_stCon.width + \
 79                   arcBufferX[imageptr]/reg1; \
 80          zptr +=  offset<<1; \
 81          reg1_save_save = reg1; \
 82          reg1 = (arcBufferZ[imageptr])/reg1 + z; \
 83          if( (Uint2)reg1>=*((Uint2Ptr)zptr)) {\
 84            *((Uint2Ptr)zptr) = (Uint2)reg1; \
 85            *((Uint1Ptr)(im_save+offset)) = \
 86               (Uint1)(color + ((arcBufferC[imageptr]*z)>>9)); \
 87          } \
 88          reg1 = reg1_save_save; \
 89          zptr = zptr_save; \
 90        } \
 91        imageptr = im_save; \
 92        reg1 = reg1_save; \
 93      } else { \
 94        reg1_save = reg1; \
 95        reg1 = (Nlm_stCon.zmaxPersp1-z); \
 96        im_save = imageptr; \
 97        imageptr = arcBTotal; \
 98        while ( imageptr > 0 ){ \
 99          imageptr--; \
100          y_cur = arcBufferY[imageptr]/reg1; \
101          x_cur = arcBufferX[imageptr]/reg1; \
102          if ( (x_cur>=arc_xmin)&&(x_cur<=arc_xmax)&& \
103               (y_cur>=arc_ymin)&&(y_cur<=arc_ymax) ){ \
104            offset = y_cur * Nlm_stCon.width + x_cur; \
105            zptr_save = zptr; \
106            zptr +=  offset<<1; \
107            reg1_save_save = reg1; \
108            reg1 = (arcBufferZ[imageptr])/reg1 + z; \
109            if( (Uint2)reg1>=*((Uint2Ptr)zptr)) {\
110              *((Uint2Ptr)zptr) = (Uint2)reg1; \
111              *((Uint1Ptr)(im_save+offset)) = \
112               (Uint1)(color + ((arcBufferC[imageptr]*z)>>9)); \
113            } \
114            reg1 = reg1_save_save; \
115            zptr = zptr_save; \
116          } \
117        } \
118        imageptr = im_save; \
119        reg1 = reg1_save; \
120      } \
121    } \
122  } else { \
123    reg1_save = reg1; \
124    reg1 = (Nlm_stCon.zmaxPersp1-z); \
125    im_save = imageptr; \
126    imageptr = arcBTotal; \
127    while ( imageptr > 0 ){ \
128      imageptr--; \
129      zptr_save = zptr; \
130      offset = (arcBufferY[imageptr]/reg1) * Nlm_stCon.width + \
131               arcBufferX[imageptr]/reg1; \
132      zptr +=  offset<<1; \
133      reg1_save_save = reg1; \
134      reg1 = (arcBufferZ[imageptr])/reg1 + z; \
135      if( (Uint2)reg1>=*((Uint2Ptr)zptr)) {\
136        *((Uint2Ptr)zptr) = (Uint2)reg1; \
137        *((Uint1Ptr)(im_save+offset)) = \
138           (Uint1)(color + ((arcBufferC[imageptr]*z)>>9)); \
139      } \
140      reg1 = reg1_save_save; \
141      zptr = zptr_save; \
142    } \
143    imageptr = im_save; \
144    reg1 = reg1_save; \
145  } \
146 } 
147 
148 #define SETARCPIXELID(zptr,imageptr,z,curID) \
149 {long offset; \
150  long y_cur; long x_cur; \
151  long reg1_save; long reg1_save_save; long zptr_save; long im_save; \
152  reg1_save = reg1; \
153  reg1 = (Nlm_stCon.zmaxPersp1-z); \
154  im_save = imageptr; \
155  imageptr = arcBTotal; \
156  while ( imageptr > 0 ){ \
157    imageptr--; \
158    y_cur = arcBufferY[imageptr]/reg1; \
159    x_cur = arcBufferX[imageptr]/reg1; \
160    if ( (x_cur>=arc_xmin)&&(x_cur<=arc_xmax)&& \
161         (y_cur>=arc_ymin)&&(y_cur<=arc_ymax) ){ \
162      offset = (y_cur * Nlm_stCon.widthCur + x_cur); \
163      zptr_save = zptr; \
164      zptr += (offset << 1); \
165      reg1_save_save = reg1; \
166      reg1 = (arcBufferZ[imageptr])/reg1 + z; \
167      if( (Uint2)reg1>=*((Uint2Ptr)zptr)) {\
168        *((Uint2Ptr)zptr) = (Uint2)reg1; \
169        *((VoidPtr*)(im_save+(offset * sizeof(Nlm_stCon.idBuffer[0])))) =curID;\
170      } \
171      reg1 = reg1_save_save; \
172      zptr = zptr_save; \
173    } \
174  } \
175  imageptr = im_save; \
176  reg1 = reg1_save; \
177 } 
178 
179 /*****************************************************************************
180 *
181 *   TYPEDEFS
182 *
183 *****************************************************************************/
184 
185 /*****************************************************************************
186 *
187 *   GLOBAL VARIABLE
188 *
189 *****************************************************************************/
190 extern Nlm_Context3D Nlm_stCon;
191 extern Uint1         Nlm_Isqrt[129*129];
192 
193 /*****************************************************************************
194 *
195 *   STATIC VARIABLE
196 *
197 *****************************************************************************/
198 static long arcBufferX[256*3];
199 static long arcBufferY[256*3];
200 static long arcBufferZ[256*3];
201 static long arcBufferC[256*3];
202 static long arcBTotal;
203 static long arcBMinX,arcBMaxX,arcBMinY,arcBMaxY;
204 
205 
206 /*****************************************************************************
207 *
208 *   FUNCTIONS
209 *
210 *****************************************************************************/
211 static void Nlm_Empty3D ( Nlm_VoidPtr p )
212 {
213 }
214 
215 /*****************************************************************************
216 *
217 *   CYLINDER
218 *
219 *****************************************************************************/
220 typedef struct Nlm_cylin3d {
221   Nlm_Base3D  base;
222   long        x1,y1,z1;
223   long        x2,y2,z2;
224   long        radius;
225 } Nlm_Cylin3D, PNTR Nlm_Cylin3DPtr;
226 
227 static void Nlm_Cylin3DDraw ( Nlm_Cylin3DPtr p )
228 {
229   register long reg1;
230   register long reg2;
231   register long reg3;
232   register long reg4;
233   double        arc_clenXY;
234   Uint1Ptr      radiusF;
235   long          c_x1,c_x2;
236   long          c_y1,c_y2;
237   long          c_z1,c_z2;
238   long          c_dx,c_dy,c_dz;
239   long          rad;
240   long          needChk;
241   long          colorW;
242   long          ystep;
243   long          zystep;
244   long          arc_x, arc_y;
245   long          arc_porErr, arc_stepErr;
246   long          arc_errX, arc_errY;
247   long          arcN_x, arcN_y, arc_z;
248   long          arcN_rMax, arcN_rMax2, arcN_rMin2;
249   long          arcN_errX, arcN_errY, arcN_errBase;
250   long          arc_stepSin, arc_stepCos;
251   long          xx1,xx2;
252   long          yy1,yy2;
253   long          zz1,zz2;
254   long          status2;
255   long          orient;
256   long          endPtr;
257   long          colorScale;
258   long          color;
259   long          offset1;
260   long          offset2;
261   long          zrate;
262   long          dx, dy;
263   long          curz;
264   long          arc_scale1;
265   long          arc_offset1;
266   long          arc_xmin, arc_ymin, arc_xmax, arc_ymax;
267 
268   reg1 = (long)p;
269 
270   /* Rotate and check */
271   reg2 = Nlm_stCon.a[0][0];
272   reg3 = ((Nlm_Cylin3DPtr)reg1)->x1 / (long)reg2;
273   reg4 = ((Nlm_Cylin3DPtr)reg1)->x2 / (long)reg2;
274   reg2 = Nlm_stCon.a[0][1];
275   reg3 += ((Nlm_Cylin3DPtr)reg1)->y1 / (long)reg2;
276   reg4 += ((Nlm_Cylin3DPtr)reg1)->y2 / (long)reg2;
277   reg2 = Nlm_stCon.a[0][2];
278   reg3 += ((Nlm_Cylin3DPtr)reg1)->z1 / (long)reg2;
279   reg4 += ((Nlm_Cylin3DPtr)reg1)->z2 / (long)reg2;
280   reg2 = Nlm_stCon.c[0];
281   reg3 += reg2;
282   reg4 += reg2;
283   c_x1 = reg3; c_x2 = reg4;
284 
285   reg2 = Nlm_stCon.a[1][0];
286   reg3 = ((Nlm_Cylin3DPtr)reg1)->x1 / (long)reg2;
287   reg4 = ((Nlm_Cylin3DPtr)reg1)->x2 / (long)reg2;
288   reg2 = Nlm_stCon.a[1][1];
289   reg3 += ((Nlm_Cylin3DPtr)reg1)->y1 / (long)reg2;
290   reg4 += ((Nlm_Cylin3DPtr)reg1)->y2 / (long)reg2;
291   reg2 = Nlm_stCon.a[1][2];
292   reg3 += ((Nlm_Cylin3DPtr)reg1)->z1 / (long)reg2;
293   reg4 += ((Nlm_Cylin3DPtr)reg1)->z2 / (long)reg2;
294   reg2 = Nlm_stCon.c[1];
295   reg3 += reg2;
296   reg4 += reg2;
297   c_y1 = reg3; c_y2 = reg4;
298 
299   reg2 = Nlm_stCon.a[2][0];
300   reg3 = ((Nlm_Cylin3DPtr)reg1)->x1 / (long)reg2;
301   reg4 = ((Nlm_Cylin3DPtr)reg1)->x2 / (long)reg2;
302   reg2 = Nlm_stCon.a[2][1];
303   reg3 += ((Nlm_Cylin3DPtr)reg1)->y1 / (long)reg2;
304   reg4 += ((Nlm_Cylin3DPtr)reg1)->y2 / (long)reg2;
305   reg2 = Nlm_stCon.a[2][2];
306   reg3 += ((Nlm_Cylin3DPtr)reg1)->z1 / (long)reg2;
307   reg4 += ((Nlm_Cylin3DPtr)reg1)->z2 / (long)reg2;
308   reg2 = Nlm_stCon.c[2];
309   reg3 += reg2;
310   reg4 += reg2;
311   c_z1 = reg3; c_z2 = reg4; c_dz = reg4-reg3;
312   if ( c_dz > 0 ){
313     reg2 = c_z1; c_z1 = c_z2; c_z2 = reg2;
314     reg2 = c_y1; c_y1 = c_y2; c_y2 = reg2;
315     reg2 = c_x1; c_x1 = c_x2; c_x2 = reg2;
316     c_dz = -c_dz;
317   }
318   reg2 = ((Nlm_Cylin3DPtr)reg1)->radius / Nlm_stCon.scale;
319   reg2 = (reg2*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z1);
320   if ( reg2 > 127 ) return;
321   if ( reg2 == 0 ) reg2 = 1;
322   radiusF = &(Nlm_Isqrt[reg2*(reg2+1)]);
323   rad = reg2;
324   needChk = 0;
325   reg2 = Nlm_stCon.width>>1;
326   reg3 = c_x1-reg2;
327   c_x1 = reg2 + (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z1);
328   reg3 = c_x2-reg2;
329   reg4 = reg2 + (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z2);
330   c_x2 = reg4;
331   reg3 = c_x1;
332   c_dx = reg4-reg3;
333   if ( reg3 < reg4 ) {
334     reg3 -= rad; reg4 += rad;
335     if ( (reg4 < Nlm_stCon.xmin)||(reg3 > Nlm_stCon.xmax) ) return;
336     reg3 -= 4; reg4 += 4;
337     if ( (reg4 > Nlm_stCon.xmax)||(reg3 < Nlm_stCon.xmin) ) needChk = 1;
338   } else {
339     reg3 += rad; reg4 -= rad;
340     if ( (reg3 < Nlm_stCon.xmin)||(reg4 > Nlm_stCon.xmax) ) return;
341     reg3 += 4; reg4 -= 4;
342     if ( (reg3 > Nlm_stCon.xmax)||(reg4 < Nlm_stCon.xmin) ) needChk = 1;
343   }
344   reg2 = Nlm_stCon.height>>1;
345   reg3 = c_y1-reg2;
346   c_y1 = reg2 Y_PLUS (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z1);
347   reg3 = c_y2-reg2;
348   reg4 = reg2 Y_PLUS (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z2);
349   c_y2 = reg4;
350   reg3 = c_y1;
351   c_dy = reg4-reg3;
352   if ( reg3 < reg4 ) {
353     reg3 -= rad; reg4 += rad;
354     if ( (reg4 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) return;
355     reg3 -= 4; reg4 += 4;
356     if ( (reg4 > Nlm_stCon.ymax)||(reg3 < Nlm_stCon.ymin) ) needChk = 1;
357   } else {
358     reg3 += rad; reg4 -= rad;
359     if ( (reg3 < Nlm_stCon.ymin)||(reg4 > Nlm_stCon.ymax) ) return;
360     reg3 += 4; reg4 -= 4;
361     if ( (reg3 > Nlm_stCon.ymax)||(reg4 < Nlm_stCon.ymin) ) needChk = 1;
362   }
363   reg3 = c_z1;
364   reg3 = (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-reg3);
365   reg4 = c_z2;
366   reg4 = (reg4*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-reg4);
367   c_z1 = reg3; c_z2 = reg4; c_dz = reg4-reg3;
368 
369   /* c_x1,c_y1,c_z1 - first (top) point    
370      c_x2,c_y2,c_z2 - second point
371      c_dx,c_dy,c_dz - vector 
372      rad            - radius
373      needChk        - 1 if need */
374 
375   if ( (c_dx==0) && (c_dy==0) ) return;
376   colorW = Nlm_stCon.colorOffset +
377     ((Nlm_Cylin3DPtr)reg1)->base.color * Nlm_stCon.colorStep + 1;
378   color = (Nlm_stCon.colorStep*141*(c_z1+Nlm_stCon.zmax))/
379     (628*Nlm_stCon.zmax) + colorW;
380   colorScale = (((rad+1)*314)<<8)/
381     (Nlm_stCon.colorStep*(50+(50*c_z1)/Nlm_stCon.zmax));
382   colorScale *= 50+(50*c_z1);
383   ystep = Nlm_stCon.width;
384   zystep = ystep<<1;
385 
386   /* Elips - start */
387   reg2 = c_dx*c_dx + c_dy*c_dy;
388   arc_clenXY = sqrt ( (double)reg2 );
389   reg3 = c_dz*c_dz;
390   reg2 += reg3;
391   reg4 = reg2/16000 + 1;
392   reg2 /= reg4;
393   reg3 /= reg4;
394   if ( reg3 == 0 ) {
395     reg2 = 16000; reg3 = 1;
396   }
397   arcN_rMax2 = reg2;
398   arcN_rMin2 = reg3;
399   reg2 = rad;
400   arc_stepCos = arc_x = (long)((double)(-c_dy*reg2)/arc_clenXY); 
401   arc_stepSin = arc_y = (long)((double)(c_dx*reg2)/arc_clenXY);
402   arcN_rMax = arc_stepErr = reg2<<2;
403   arc_porErr = reg2<<1;
404   arcN_x= -arcN_rMax; arcN_y = 0;
405   arcN_errBase = 0;
406   arc_x--; 
407   arc_errX = arc_stepErr; arc_errY = 0;
408   arcBTotal = 0;
409   arcBMinX = arcBMinY = -1000;
410   arcBMaxX = arcBMaxY = 1000;
411   arc_scale1 = (Nlm_stCon.zmaxPersp1-c_z1);
412   arc_offset1 = arc_scale1>>1;
413   do {
414     for ( ;; ){
415       reg1 = arc_porErr;
416       reg3 = arc_errX; reg4 = arc_errY;
417       if ( reg3 > reg1 ){
418         arc_x ++; reg3 -= arc_stepErr;
419       } else if ( reg3 < -reg1 ){
420         arc_x --; reg3 += arc_stepErr;
421       } else if ( reg4 > reg1 ){
422         arc_y ++; reg4 -= arc_stepErr;
423       } else if ( reg4 < -reg1 ){
424         arc_y --; reg4 += arc_stepErr;
425       } else break;
426       arc_errX = reg3; arc_errY = reg4;
427       /* we have arc_x, arc_y, rad and radiusF */
428       reg1 = arc_y;
429       if ( reg1 < 0 ) reg1 = -reg1;
430       reg1 = (long)radiusF[reg1];
431       if ( arc_x > reg1 ) {
432         /*arc_x = reg1;*/
433         arc_z = 0;
434       } else if ( arc_x < -reg1 ) {
435         /*arc_x = -reg1;*/
436         arc_z = 0;
437       } else {
438         arc_z = Nlm_Isqrt[reg1*(reg1+1)+arc_x];
439       }
440       /* we have arc_x, arc_y, arc_z and rad */
441       arcBufferC[arcBTotal] = ((50*(arc_z-arc_x Y_PLUS arc_y))<<17)/colorScale;
442       arcBufferX[arcBTotal] = arc_x*arc_scale1+arc_offset1;
443       arcBufferY[arcBTotal] = arc_y*arc_scale1+arc_offset1;
444       arcBufferZ[arcBTotal++] = arc_z*arc_scale1+arc_offset1;
445       if ( needChk ) {
446         if ( arcBMinX > arc_x ) arcBMinX = arc_x;
447         if ( arcBMaxX < arc_x ) arcBMaxX = arc_x;
448         if ( arcBMinY > arc_y ) arcBMinY = arc_y;
449         if ( arcBMaxY < arc_y ) arcBMaxY = arc_y;
450       }
451     }
452     if ( arcN_x < 0 ){
453       arcN_errX = arcN_errBase + (arcN_x<<1) + 1;
454       arcN_errY = arcN_errBase + (arcN_rMax2*((arcN_y<<1) + 1))/arcN_rMin2;
455       if ( arcN_errX <= 0 ){
456         if ( (arcN_errY <= 0) && (arcN_errY > arcN_errX) ){
457           arcN_y++; arcN_errBase = arcN_errY; 
458           arc_errX += arc_stepSin; arc_errY -= arc_stepCos;
459         } else {
460           arcN_x++; arcN_errBase = arcN_errX; 
461           arc_errX -= arc_stepCos; arc_errY -= arc_stepSin;
462         }
463       } else {
464         arcN_y++; arcN_errBase = arcN_errY; 
465         arc_errX += arc_stepSin; arc_errY -= arc_stepCos;
466       }
467     } else {
468       arcN_errX = arcN_errBase + (arcN_x<<1) + 1;
469       arcN_errY = arcN_errBase + (arcN_rMax2*(-(arcN_y<<1) + 1))/arcN_rMin2;
470       if ( (arcN_errY <= 0) && (arcN_y > 0) ){
471         if ( (arcN_errX <= 0) && (arcN_errX > arcN_errY) ){
472           arcN_x++; arcN_errBase = arcN_errX; 
473           arc_errX -= arc_stepCos; arc_errY -= arc_stepSin;
474         } else {
475           arcN_y--; arcN_errBase = arcN_errY; 
476           arc_errX -= arc_stepSin; arc_errY += arc_stepCos;
477         }
478       } else {
479         arcN_x++; arcN_errBase = arcN_errX; 
480         arc_errX -= arc_stepCos; arc_errY -= arc_stepSin;
481       }
482     }
483   } while ( (arcN_x <= arcN_rMax)&&(arcN_y >= 0) );
484   reg1 = rad;
485   Nlm_stCon.xmin -= reg1;
486   Nlm_stCon.xmax += reg1; 
487   Nlm_stCon.ymin -= reg1;
488   Nlm_stCon.ymax += reg1;
489   if ( needChk ) {
490     /* Calculate status1(reg1) and status2(reg2) */
491     reg1 = 0;
492     reg2 = 0;
493     reg3 = c_x1;
494     reg4 = Nlm_stCon.xmin;
495     if ( reg3 < reg4 ) reg1 = 1;
496     else if ( reg3 > Nlm_stCon.xmax ) reg1 = 2;
497     reg3 = c_x2;
498     if ( reg3 < reg4 ) reg2 = 1;
499     else if ( reg3 > Nlm_stCon.xmax ) reg2 = 2;
500 
501     reg3 = c_y1;
502     reg4 = Nlm_stCon.ymin;
503     if ( reg3 < reg4 ) reg1 += 6;
504     else if ( reg3 > Nlm_stCon.ymax ) reg1 += 3;
505     reg3 = c_y2;
506     if ( reg3 < reg4 ) reg2 += 6;
507     else if ( reg3 > Nlm_stCon.ymax ) reg2 += 3;
508 
509     /* Save status2*/
510     status2 = reg2;
511 
512     /* Calculate the first point (xx1,yy1,zz1)*/
513     switch ( reg1 ) {
514       case 0: 
515         xx1 = c_x1; yy1=c_y1; zz1=c_z1;
516         break;
517       case 1:
518         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
519         reg4 = c_x2-reg1;
520         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
521         yy1 = reg3;
522         xx1 = reg2;
523         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
524         break;
525       case 2:
526         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
527         reg4 = c_x2-reg1;
528         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
529         yy1 = reg3;
530         xx1 = reg2;
531         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
532         break;
533       case 3:
534         reg1 = c_y1; reg2 = Nlm_stCon.ymax;
535         reg4 = c_y2-reg1;
536         reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
537         xx1 = reg3;
538         yy1 = reg2;
539         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
540         break;
541       case 4:
542         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
543         reg4 = c_x2-reg1;
544         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
545         yy1 = reg3;
546         xx1 = reg2;
547         if ( (reg3 < Nlm_stCon.ymin) || (reg3 > Nlm_stCon.ymax) ) {
548           reg1 = c_y1; reg2 = Nlm_stCon.ymax;
549           reg4 = c_y2-reg1;
550           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
551           xx1 = reg3;
552           yy1 = reg2;
553         }
554         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
555         break;
556       case 5:
557         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
558         reg4 = c_x2-reg1;
559         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
560         yy1 = reg3;
561         xx1 = reg2;
562         if ( (reg3 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
563           reg1 = c_y1; reg2 = Nlm_stCon.ymax;
564           reg4 = c_y2-reg1;
565           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
566           xx1 = reg3;
567           yy1 = reg2;
568         }
569         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
570         break;
571       case 6:
572         reg1 = c_y1; reg2 = Nlm_stCon.ymin;
573         reg4 = c_y2-reg1;
574         reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
575         xx1 = reg3;
576         yy1 = reg2;
577         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
578         break;
579       case 7:
580         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
581         reg4 = c_x2-reg1;
582         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
583         yy1 = reg3;
584         xx1 = reg2;
585         if ( (reg3 < Nlm_stCon.ymin) || (reg3 > Nlm_stCon.ymax) ) {
586           reg1 = c_y1; reg2 = Nlm_stCon.ymin;
587           reg4 = c_y2-reg1;
588           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
589           xx1 = reg3;
590           yy1 = reg2;
591         }
592         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
593         break;
594       default:
595         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
596         reg4 = c_x2-reg1;
597         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
598         yy1 = reg3;
599         xx1 = reg2;
600         if ( (reg3 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
601           reg1 = c_y1; reg2 = Nlm_stCon.ymin;
602           reg4 = c_y2-reg1;
603           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
604           xx1 = reg3;
605           yy1 = reg2;
606         }
607         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
608     }
609 
610     /* Calculate the second point (xx2,yy2,zz2)*/
611     switch ( status2 ) {
612       case 0: 
613         xx2 = c_x2; yy2=c_y2; zz2=c_z2;
614         break;
615       case 1:
616         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
617         reg4 = c_x2-reg1;
618         yy2 = c_y1 + c_dy*(reg2-reg1)/reg4;
619         xx2 = reg2;
620         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
621         break;
622       case 2:
623         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
624         reg4 = c_x2-reg1;
625         yy2 = c_y1 + c_dy*(reg2-reg1)/reg4;
626         xx2 = reg2;
627         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
628         break;
629       case 3:
630         reg1 = c_y1; reg2 = Nlm_stCon.ymax;
631         reg4 = c_y2-reg1;
632         xx2 = c_x1 + c_dx*(reg2-reg1)/reg4;
633         yy2 = reg2;
634         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
635         break;
636       case 4:
637         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
638         reg4 = c_x2-reg1;
639         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
640         yy2 = reg3;
641         xx2 = reg2;
642         if ( (reg3 < Nlm_stCon.ymin) || (reg3 > Nlm_stCon.ymax) ) {
643           reg1 = c_y1; reg2 = Nlm_stCon.ymax;
644           reg4 = c_y2-reg1;
645           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
646           xx2 = reg3;
647           yy2 = reg2;
648         }
649         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
650         break;
651       case 5:
652         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
653         reg4 = c_x2-reg1;
654         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
655         yy2 = reg3;
656         xx2 = reg2;
657         if ( (reg3 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
658           reg1 = c_y1; reg2 = Nlm_stCon.ymax;
659           reg4 = c_y2-reg1;
660           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
661           xx2 = reg3;
662           yy2 = reg2;
663         }
664         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
665         break;
666       case 6:
667         reg1 = c_y1; reg2 = Nlm_stCon.ymin;
668         reg4 = c_y2-reg1;
669         xx2 = c_x1 + c_dx*(reg2-reg1)/reg4;
670         yy2 = reg2;
671         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
672         break;
673       case 7:
674         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
675         reg4 = c_x2-reg1;
676         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
677         yy2 = reg3;
678         xx2 = reg2;
679         if ( (reg3 < Nlm_stCon.ymin) || (reg3 > Nlm_stCon.ymax) ) {
680           reg1 = c_y1; reg2 = Nlm_stCon.ymin;
681           reg4 = c_y2-reg1;
682           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
683           xx2 = reg3;
684           yy2 = reg2;
685         }
686         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
687         break;
688       default:
689         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
690         reg4 = c_x2-reg1;
691         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
692         yy2 = reg3;
693         xx2 = reg2;
694         if ( (reg3 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
695           reg1 = c_y1; reg2 = Nlm_stCon.ymin;
696           reg4 = c_y2-reg1;
697           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
698           xx2 = reg3;
699           yy2 = reg2;
700         }
701         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
702     }
703     if ( (xx1==xx2) && (yy1==yy2) ) {
704       reg1 = rad;
705       Nlm_stCon.xmin += reg1;
706       Nlm_stCon.xmax -= reg1; 
707       Nlm_stCon.ymin += reg1;
708       Nlm_stCon.ymax -= reg1; 
709       return;
710     }
711   } else {
712     yy1 = c_y1; yy2 = c_y2;
713     xx1 = c_x1; xx2= c_x2;
714     zz1= c_z1; zz2 = c_z2;
715   }
716   reg3 = xx1;
717   reg4 = xx2;
718   if ( reg3 < reg4 ) {
719     if ( (reg3 < Nlm_stCon.xmin)||(reg4 > Nlm_stCon.xmax) ) {
720       reg1 = rad;
721       Nlm_stCon.xmin += reg1;
722       Nlm_stCon.xmax -= reg1; 
723       Nlm_stCon.ymin += reg1;
724       Nlm_stCon.ymax -= reg1; 
725       return;
726     }
727     reg1 = 0;
728   } else {
729     if ( (reg4 < Nlm_stCon.xmin)||(reg3 > Nlm_stCon.xmax) ) {
730       reg1 = rad;
731       Nlm_stCon.xmin += reg1;
732       Nlm_stCon.xmax -= reg1; 
733       Nlm_stCon.ymin += reg1;
734       Nlm_stCon.ymax -= reg1;
735       return;
736     }
737     reg1 = 1;
738   }
739   reg3 = yy1;
740   reg4 = yy2;
741   if ( reg3 < reg4 ) {
742     if ( (reg3 < Nlm_stCon.ymin)||(reg4 > Nlm_stCon.ymax) ) {
743       reg1 = rad;
744       Nlm_stCon.xmin += reg1;
745       Nlm_stCon.xmax -= reg1; 
746       Nlm_stCon.ymin += reg1;
747       Nlm_stCon.ymax -= reg1; 
748       return;
749     }
750   } else {
751     if ( (reg4 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
752       reg1 = rad;
753       Nlm_stCon.xmin += reg1;
754       Nlm_stCon.xmax -= reg1; 
755       Nlm_stCon.ymin += reg1;
756       Nlm_stCon.ymax -= reg1; 
757       return;
758     }
759     reg1 |= 0x2;
760   }
761   orient = reg1;
762   reg1 = rad;
763   Nlm_stCon.xmin += reg1;
764   Nlm_stCon.xmax -= reg1; 
765   Nlm_stCon.ymin += reg1;
766   Nlm_stCon.ymax -= reg1;
767 
768   /* Calculate offsets and pointers */
769   reg1 = yy1 * Nlm_stCon.width + xx1;
770   offset1 = reg1;
771   reg3 = (long)(Nlm_stCon.image + reg1);
772   reg2 = yy2 * Nlm_stCon.width + xx2;
773   offset2 = reg2;
774   reg4 = (long)(Nlm_stCon.image + reg2);
775   /* reg3 - statrt reg4 - end */
776 
777   /* Will be:
778      reg1 - last orientation
779      reg2 - zz1
780      reg3 - start
781      reg4 - zPtr
782      endPtr saved in endPtr */
783   reg1 = orient;
784   switch ( reg1 ){
785     case 0:
786       dy = yy2 - yy1;
787       reg2 = xx2 - xx1;
788       dx = reg2;
789       if ( reg2>dy ) {
790         zrate = ((zz2 - zz1)<<10)/reg2;
791       } else {
792         zrate = ((zz2 - zz1)<<10)/dy;
793         reg1 = 2;
794       }
795       reg2 = zz1;
796       endPtr = reg4;
797       arc_xmin = Nlm_stCon.xmin - xx1;
798       arc_xmax = Nlm_stCon.xmax - xx1;
799       arc_ymin = Nlm_stCon.ymin - yy1;
800       arc_ymax = Nlm_stCon.ymax - yy1;
801       reg4 = (long)(Nlm_stCon.zBuffer + offset1);
802       break;
803     case 1:
804       dy = yy2 - yy1;
805       reg2 = xx1 - xx2;
806       if ( reg2 > dy ) {
807         zrate = ((zz1 - zz2)<<10)/reg2;
808       } else {
809         zrate = ((zz1 - zz2)<<10)/dy;
810         reg1 = 3;
811       }
812       dx = reg2;
813       reg2 = reg3; reg3 = reg4; reg4 = reg2;
814       reg2 = zz2;
815       endPtr = reg4;
816       arc_xmin = Nlm_stCon.xmin - xx2;
817       arc_xmax = Nlm_stCon.xmax - xx2;
818       arc_ymin = Nlm_stCon.ymin - yy2;
819       arc_ymax = Nlm_stCon.ymax - yy2;
820       reg4 = (long)(Nlm_stCon.zBuffer + offset2);
821       break;
822     case 2:
823       dy = yy1 - yy2;
824       reg2 = xx2 - xx1;
825       if ( reg2 > dy ){
826         zrate = ((zz2 - zz1)<<10)/reg2;
827         reg1 = 1;
828       } else {
829         zrate = ((zz2 - zz1)<<10)/dy;
830         reg1 = 3;
831       }
832       dx = reg2;
833       reg2 = zz1;
834       endPtr = reg4;
835       arc_xmin = Nlm_stCon.xmin - xx1;
836       arc_xmax = Nlm_stCon.xmax - xx1;
837       arc_ymin = Nlm_stCon.ymin - yy1;
838       arc_ymax = Nlm_stCon.ymax - yy1;
839       reg4 = (long)(Nlm_stCon.zBuffer + offset1);
840       break;
841     default:
842       dy = yy1 - yy2;
843       reg2 = xx1 - xx2;
844       if ( reg2 > dy ){
845         zrate = ((zz1 - zz2)<<10)/reg2;
846         reg1 = 0;
847       } else {
848         zrate = ((zz1 - zz2)<<10)/dy;
849         reg1 = 2;
850       }
851       dx = reg2;
852       reg2 = reg3; reg3 = reg4; reg4 = reg2;
853       reg2 = zz2;
854       endPtr = reg4;
855       arc_xmin = Nlm_stCon.xmin - xx2;
856       arc_xmax = Nlm_stCon.xmax - xx2;
857       arc_ymin = Nlm_stCon.ymin - yy2;
858       arc_ymax = Nlm_stCon.ymax - yy2;
859       reg4 = (long)(Nlm_stCon.zBuffer + offset2);
860   }
861 
862   SETARCPIXEL(reg4,reg3,reg2);
863   reg2 <<= 10;
864   /* Will be: reg1 - err */
865   switch ( reg1 ){
866     case 0:
867       reg1 = -(dx>>1);
868       do {
869         reg1 += dy;
870         if ( reg1 > 0 ){
871            reg3 += ystep; 
872            arc_ymin--;
873            arc_ymax--;
874            reg4 += zystep; 
875            reg1 -= dx; 
876         }
877         reg3++; reg4++; reg4++;
878         arc_xmin--;
879         arc_xmax--;
880         reg2 += zrate; 
881         curz = reg2;
882         reg2 >>= 10;
883         SETARCPIXEL(reg4,reg3,reg2);
884         reg2 = curz;
885       } while ( reg3 != endPtr );
886       break;
887     case 1:
888       reg1 = -(dx>>1);
889       do {
890         reg1 += dy;
891         if ( reg1 > 0 ){
892            reg3 -= ystep; 
893            arc_ymin++;
894            arc_ymax++;
895            reg4 -= zystep; 
896            reg1 -= dx; 
897         }
898         reg3++; reg4++; reg4++;
899         arc_xmin--;
900         arc_xmax--;
901         reg2 += zrate; 
902         curz = reg2;
903         reg2 >>= 10;
904         SETARCPIXEL(reg4,reg3,reg2);
905         reg2 = curz;
906       } while ( reg3 != endPtr );
907       break;
908     case 2:
909       reg1 = -(dy>>1);
910       do {
911         reg1 += dx;
912         if ( reg1 > 0 ) {
913            reg3 ++;
914            arc_xmin--;
915            arc_xmax--;
916            reg4 ++; reg4++;
917            reg1 -= dy; 
918         }
919         reg3 += ystep; 
920         arc_ymin--;
921         arc_ymax--;
922         reg4 += zystep; 
923         reg2 += zrate; 
924         curz = reg2;
925         reg2 >>= 10;
926         SETARCPIXEL(reg4,reg3,reg2);
927         reg2 = curz;
928       } while ( reg3 != endPtr );
929       break;
930     default:
931       reg1 = -(dy>>1);
932       do {
933         reg1 += dx;
934         if ( reg1 > 0 ) {
935            reg3 ++;
936            arc_xmin--;
937            arc_xmax--;
938            reg4 ++; reg4++;
939            reg1 -= dy; 
940         }
941         reg3 -= ystep; 
942         arc_ymin++;
943         arc_ymax++;
944         reg4 -= zystep; 
945         reg2 += zrate; 
946         curz = reg2;
947         reg2 >>= 10;
948         SETARCPIXEL(reg4,reg3,reg2);
949         reg2 = curz;
950       } while ( reg3 != endPtr );
951   }
952 }
953 
954 static void Nlm_Cylin3DHitT ( Nlm_Cylin3DPtr p )
955 {
956   register long reg1;
957   register long reg2;
958   register long reg3;
959   register long reg4;
960   double        arc_clenXY;
961   Uint1Ptr      radiusF;
962   long          c_x1,c_x2;
963   long          c_y1,c_y2;
964   long          c_z1,c_z2;
965   long          c_dx,c_dy,c_dz;
966   long          rad;
967   long          needChk;
968   long          ystep;
969   long          zystep;
970   long          arc_x, arc_y;
971   long          arc_porErr, arc_stepErr;
972   long          arc_errX, arc_errY;
973   long          arcN_x, arcN_y, arc_z;
974   long          arcN_rMax, arcN_rMax2, arcN_rMin2;
975   long          arcN_errX, arcN_errY, arcN_errBase;
976   long          arc_stepSin, arc_stepCos;
977   long          xx1,xx2;
978   long          yy1,yy2;
979   long          zz1,zz2;
980   long          status2;
981   long          orient;
982   long          endPtr;
983   long          offset1;
984   long          offset2;
985   long          zrate;
986   long          dx, dy;
987   long          curz;
988   long          arc_scale1;
989   long          arc_offset1;
990   long          arc_xmin, arc_ymin, arc_xmax, arc_ymax;
991 
992   reg1 = (long)p;
993 
994   /* Rotate and check */
995   reg2 = Nlm_stCon.a[0][0];
996   reg3 = ((Nlm_Cylin3DPtr)reg1)->x1 / (long)reg2;
997   reg4 = ((Nlm_Cylin3DPtr)reg1)->x2 / (long)reg2;
998   reg2 = Nlm_stCon.a[0][1];
999   reg3 += ((Nlm_Cylin3DPtr)reg1)->y1 / (long)reg2;
1000   reg4 += ((Nlm_Cylin3DPtr)reg1)->y2 / (long)reg2;
1001   reg2 = Nlm_stCon.a[0][2];
1002   reg3 += ((Nlm_Cylin3DPtr)reg1)->z1 / (long)reg2;
1003   reg4 += ((Nlm_Cylin3DPtr)reg1)->z2 / (long)reg2;
1004   reg2 = Nlm_stCon.c[0];
1005   reg3 += reg2;
1006   reg4 += reg2;
1007   c_x1 = reg3; c_x2 = reg4;
1008 
1009   reg2 = Nlm_stCon.a[1][0];
1010   reg3 = ((Nlm_Cylin3DPtr)reg1)->x1 / (long)reg2;
1011   reg4 = ((Nlm_Cylin3DPtr)reg1)->x2 / (long)reg2;
1012   reg2 = Nlm_stCon.a[1][1];
1013   reg3 += ((Nlm_Cylin3DPtr)reg1)->y1 / (long)reg2;
1014   reg4 += ((Nlm_Cylin3DPtr)reg1)->y2 / (long)reg2;
1015   reg2 = Nlm_stCon.a[1][2];
1016   reg3 += ((Nlm_Cylin3DPtr)reg1)->z1 / (long)reg2;
1017   reg4 += ((Nlm_Cylin3DPtr)reg1)->z2 / (long)reg2;
1018   reg2 = Nlm_stCon.c[1];
1019   reg3 += reg2;
1020   reg4 += reg2;
1021   c_y1 = reg3; c_y2 = reg4;
1022 
1023   reg2 = Nlm_stCon.a[2][0];
1024   reg3 = ((Nlm_Cylin3DPtr)reg1)->x1 / (long)reg2;
1025   reg4 = ((Nlm_Cylin3DPtr)reg1)->x2 / (long)reg2;
1026   reg2 = Nlm_stCon.a[2][1];
1027   reg3 += ((Nlm_Cylin3DPtr)reg1)->y1 / (long)reg2;
1028   reg4 += ((Nlm_Cylin3DPtr)reg1)->y2 / (long)reg2;
1029   reg2 = Nlm_stCon.a[2][2];
1030   reg3 += ((Nlm_Cylin3DPtr)reg1)->z1 / (long)reg2;
1031   reg4 += ((Nlm_Cylin3DPtr)reg1)->z2 / (long)reg2;
1032   reg2 = Nlm_stCon.c[2];
1033   reg3 += reg2;
1034   reg4 += reg2;
1035   c_z1 = reg3; c_z2 = reg4; c_dz = reg4-reg3;
1036   if ( c_dz > 0 ){
1037     reg2 = c_z1; c_z1 = c_z2; c_z2 = reg2;
1038     reg2 = c_y1; c_y1 = c_y2; c_y2 = reg2;
1039     reg2 = c_x1; c_x1 = c_x2; c_x2 = reg2;
1040     c_dz = -c_dz;
1041   }
1042   reg2 = ((Nlm_Cylin3DPtr)reg1)->radius / Nlm_stCon.scale;
1043   reg2 = (reg2*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z1);
1044   if ( reg2 > 127 ) return;
1045   if ( reg2 == 0 ) reg2 = 1;
1046   radiusF = &(Nlm_Isqrt[reg2*(reg2+1)]);
1047   rad = reg2;
1048   needChk = 0;
1049   reg2 = Nlm_stCon.width>>1;
1050   reg3 = c_x1-reg2;
1051   c_x1 = reg2 + (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z1);
1052   reg3 = c_x2-reg2;
1053   reg4 = reg2 + (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z2);
1054   c_x2 = reg4;
1055   reg3 = c_x1;
1056   c_dx = reg4-reg3;
1057   if ( reg3 < reg4 ) {
1058     reg3 -= rad; reg4 += rad;
1059     if ( (reg4 < Nlm_stCon.xmin)||(reg3 > Nlm_stCon.xmax) ) return;
1060     reg3 -= 4; reg4 += 4;
1061     if ( (reg4 > Nlm_stCon.xmax)||(reg3 < Nlm_stCon.xmin) ) needChk = 1;
1062   } else {
1063     reg3 += rad; reg4 -= rad;
1064     if ( (reg3 < Nlm_stCon.xmin)||(reg4 > Nlm_stCon.xmax) ) return;
1065     reg3 += 4; reg4 -= 4;
1066     if ( (reg3 > Nlm_stCon.xmax)||(reg4 < Nlm_stCon.xmin) ) needChk = 1;
1067   }
1068   reg2 = Nlm_stCon.height>>1;
1069   reg3 = c_y1-reg2;
1070   c_y1 = reg2 Y_PLUS (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z1);
1071   reg3 = c_y2-reg2;
1072   reg4 = reg2 Y_PLUS (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-c_z2);
1073   c_y2 = reg4;
1074   reg3 = c_y1;
1075   c_dy = reg4-reg3;
1076   if ( reg3 < reg4 ) {
1077     reg3 -= rad; reg4 += rad;
1078     if ( (reg4 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) return;
1079     reg3 -= 4; reg4 += 4;
1080     if ( (reg4 > Nlm_stCon.ymax)||(reg3 < Nlm_stCon.ymin) ) needChk = 1;
1081   } else {
1082     reg3 += rad; reg4 -= rad;
1083     if ( (reg3 < Nlm_stCon.ymin)||(reg4 > Nlm_stCon.ymax) ) return;
1084     reg3 += 4; reg4 -= 4;
1085     if ( (reg3 > Nlm_stCon.ymax)||(reg4 < Nlm_stCon.ymin) ) needChk = 1;
1086   }
1087   reg3 = c_z1;
1088   reg3 = (reg3*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-reg3);
1089   reg4 = c_z2;
1090   reg4 = (reg4*Nlm_stCon.zmaxPersp)/(Nlm_stCon.zmaxPersp1-reg4);
1091   c_z1 = reg3; c_z2 = reg4; c_dz = reg4-reg3;
1092 
1093   /* c_x1,c_y1,c_z1 - first (top) point    
1094      c_x2,c_y2,c_z2 - second point
1095      c_dx,c_dy,c_dz - vector 
1096      rad            - radius
1097      needChk        - 1 if need */
1098 
1099   if ( (c_dx==0) && (c_dy==0) )
1100     return;
1101   ystep  = Nlm_stCon.widthCur * sizeof(Nlm_stCon.idBuffer[0]);
1102   zystep = Nlm_stCon.widthCur * sizeof(Nlm_stCon.zBuffer[0]);
1103 
1104   /* Elips - start */
1105   reg2 = c_dx*c_dx + c_dy*c_dy;
1106   arc_clenXY = sqrt ( (double)reg2 );
1107   reg3 = c_dz*c_dz;
1108   reg2 += reg3;
1109   reg4 = reg2/16000 + 1;
1110   reg2 /= reg4;
1111   reg3 /= reg4;
1112   if ( reg3 == 0 ) {
1113     reg2 = 16000; reg3 = 1;
1114   }
1115   arcN_rMax2 = reg2;
1116   arcN_rMin2 = reg3;
1117   reg2 = rad;
1118   arc_stepCos = arc_x = (long)((double)(-c_dy*reg2)/arc_clenXY); 
1119   arc_stepSin = arc_y = (long)((double)(c_dx*reg2)/arc_clenXY);
1120   arcN_rMax = arc_stepErr = reg2<<2;
1121   arc_porErr = reg2<<1;
1122   arcN_x= -arcN_rMax; arcN_y = 0;
1123   arcN_errBase = 0;
1124   arc_x--; 
1125   arc_errX = arc_stepErr; arc_errY = 0;
1126   arcBTotal = 0;
1127   arcBMinX = arcBMinY = -1000;
1128   arcBMaxX = arcBMaxY = 1000;
1129   arc_scale1 = (Nlm_stCon.zmaxPersp1-c_z1);
1130   arc_offset1 = arc_scale1>>1;
1131   do {
1132     for ( ;; ){
1133       reg1 = arc_porErr;
1134       reg3 = arc_errX; reg4 = arc_errY;
1135       if ( reg3 > reg1 ){
1136         arc_x ++; reg3 -= arc_stepErr;
1137       } else if ( reg3 < -reg1 ){
1138         arc_x --; reg3 += arc_stepErr;
1139       } else if ( reg4 > reg1 ){
1140         arc_y ++; reg4 -= arc_stepErr;
1141       } else if ( reg4 < -reg1 ){
1142         arc_y --; reg4 += arc_stepErr;
1143       } else break;
1144       arc_errX = reg3; arc_errY = reg4;
1145       /* we have arc_x, arc_y, rad and radiusF */
1146       reg1 = arc_y;
1147       if ( reg1 < 0 ) reg1 = -reg1;
1148       reg1 = (long)radiusF[reg1];
1149       if ( arc_x > reg1 ) {
1150         /*arc_x = reg1;*/
1151         arc_z = 0;
1152       } else if ( arc_x < -reg1 ) {
1153         /*arc_x = -reg1;*/
1154         arc_z = 0;
1155       } else {
1156         arc_z = Nlm_Isqrt[reg1*(reg1+1)+arc_x];
1157       }
1158       /* we have arc_x, arc_y, arc_z and rad */
1159       arcBufferX[arcBTotal] = arc_x*arc_scale1+arc_offset1;
1160       arcBufferY[arcBTotal] = arc_y*arc_scale1+arc_offset1;
1161       arcBufferZ[arcBTotal++] = arc_z*arc_scale1+arc_offset1;
1162       if ( needChk ) {
1163         if ( arcBMinX > arc_x ) arcBMinX = arc_x;
1164         if ( arcBMaxX < arc_x ) arcBMaxX = arc_x;
1165         if ( arcBMinY > arc_y ) arcBMinY = arc_y;
1166         if ( arcBMaxY < arc_y ) arcBMaxY = arc_y;
1167       }
1168     }
1169     if ( arcN_x < 0 ){
1170       arcN_errX = arcN_errBase + (arcN_x<<1) + 1;
1171       arcN_errY = arcN_errBase + (arcN_rMax2*((arcN_y<<1) + 1))/arcN_rMin2;
1172       if ( arcN_errX <= 0 ){
1173         if ( (arcN_errY <= 0) && (arcN_errY > arcN_errX) ){
1174           arcN_y++; arcN_errBase = arcN_errY; 
1175           arc_errX += arc_stepSin; arc_errY -= arc_stepCos;
1176         } else {
1177           arcN_x++; arcN_errBase = arcN_errX; 
1178           arc_errX -= arc_stepCos; arc_errY -= arc_stepSin;
1179         }
1180       } else {
1181         arcN_y++; arcN_errBase = arcN_errY; 
1182         arc_errX += arc_stepSin; arc_errY -= arc_stepCos;
1183       }
1184     } else {
1185       arcN_errX = arcN_errBase + (arcN_x<<1) + 1;
1186       arcN_errY = arcN_errBase + (arcN_rMax2*(-(arcN_y<<1) + 1))/arcN_rMin2;
1187       if ( (arcN_errY <= 0) && (arcN_y > 0) ){
1188         if ( (arcN_errX <= 0) && (arcN_errX > arcN_errY) ){
1189           arcN_x++; arcN_errBase = arcN_errX; 
1190           arc_errX -= arc_stepCos; arc_errY -= arc_stepSin;
1191         } else {
1192           arcN_y--; arcN_errBase = arcN_errY; 
1193           arc_errX -= arc_stepSin; arc_errY += arc_stepCos;
1194         }
1195       } else {
1196         arcN_x++; arcN_errBase = arcN_errX; 
1197         arc_errX -= arc_stepCos; arc_errY -= arc_stepSin;
1198       }
1199     }
1200   } while ( (arcN_x <= arcN_rMax)&&(arcN_y >= 0) );
1201   reg1 = rad;
1202   Nlm_stCon.xmin -= reg1;
1203   Nlm_stCon.xmax += reg1; 
1204   Nlm_stCon.ymin -= reg1;
1205   Nlm_stCon.ymax += reg1;
1206   if ( needChk ) {
1207     /* Calculate status1(reg1) and status2(reg2) */
1208     reg1 = 0;
1209     reg2 = 0;
1210     reg3 = c_x1;
1211     reg4 = Nlm_stCon.xmin;
1212     if ( reg3 < reg4 ) reg1 = 1;
1213     else if ( reg3 > Nlm_stCon.xmax ) reg1 = 2;
1214     reg3 = c_x2;
1215     if ( reg3 < reg4 ) reg2 = 1;
1216     else if ( reg3 > Nlm_stCon.xmax ) reg2 = 2;
1217 
1218     reg3 = c_y1;
1219     reg4 = Nlm_stCon.ymin;
1220     if ( reg3 < reg4 ) reg1 += 6;
1221     else if ( reg3 > Nlm_stCon.ymax ) reg1 += 3;
1222     reg3 = c_y2;
1223     if ( reg3 < reg4 ) reg2 += 6;
1224     else if ( reg3 > Nlm_stCon.ymax ) reg2 += 3;
1225 
1226     /* Save status2*/
1227     status2 = reg2;
1228 
1229     /* Calculate the first point (xx1,yy1,zz1)*/
1230     switch ( reg1 ) {
1231       case 0: 
1232         xx1 = c_x1; yy1=c_y1; zz1=c_z1;
1233         break;
1234       case 1:
1235         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
1236         reg4 = c_x2-reg1;
1237         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1238         yy1 = reg3;
1239         xx1 = reg2;
1240         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
1241         break;
1242       case 2:
1243         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
1244         reg4 = c_x2-reg1;
1245         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1246         yy1 = reg3;
1247         xx1 = reg2;
1248         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
1249         break;
1250       case 3:
1251         reg1 = c_y1; reg2 = Nlm_stCon.ymax;
1252         reg4 = c_y2-reg1;
1253         reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1254         xx1 = reg3;
1255         yy1 = reg2;
1256         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
1257         break;
1258       case 4:
1259         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
1260         reg4 = c_x2-reg1;
1261         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1262         yy1 = reg3;
1263         xx1 = reg2;
1264         if ( (reg3 < Nlm_stCon.ymin) || (reg3 > Nlm_stCon.ymax) ) {
1265           reg1 = c_y1; reg2 = Nlm_stCon.ymax;
1266           reg4 = c_y2-reg1;
1267           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1268           xx1 = reg3;
1269           yy1 = reg2;
1270         }
1271         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
1272         break;
1273       case 5:
1274         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
1275         reg4 = c_x2-reg1;
1276         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1277         yy1 = reg3;
1278         xx1 = reg2;
1279         if ( (reg3 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
1280           reg1 = c_y1; reg2 = Nlm_stCon.ymax;
1281           reg4 = c_y2-reg1;
1282           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1283           xx1 = reg3;
1284           yy1 = reg2;
1285         }
1286         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
1287         break;
1288       case 6:
1289         reg1 = c_y1; reg2 = Nlm_stCon.ymin;
1290         reg4 = c_y2-reg1;
1291         reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1292         xx1 = reg3;
1293         yy1 = reg2;
1294         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
1295         break;
1296       case 7:
1297         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
1298         reg4 = c_x2-reg1;
1299         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1300         yy1 = reg3;
1301         xx1 = reg2;
1302         if ( (reg3 < Nlm_stCon.ymin) || (reg3 > Nlm_stCon.ymax) ) {
1303           reg1 = c_y1; reg2 = Nlm_stCon.ymin;
1304           reg4 = c_y2-reg1;
1305           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1306           xx1 = reg3;
1307           yy1 = reg2;
1308         }
1309         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
1310         break;
1311       default:
1312         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
1313         reg4 = c_x2-reg1;
1314         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1315         yy1 = reg3;
1316         xx1 = reg2;
1317         if ( (reg3 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
1318           reg1 = c_y1; reg2 = Nlm_stCon.ymin;
1319           reg4 = c_y2-reg1;
1320           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1321           xx1 = reg3;
1322           yy1 = reg2;
1323         }
1324         zz1 = c_z1 + c_dz*(reg2-reg1)/reg4;
1325     }
1326 
1327     /* Calculate the second point (xx2,yy2,zz2)*/
1328     switch ( status2 ) {
1329       case 0: 
1330         xx2 = c_x2; yy2=c_y2; zz2=c_z2;
1331         break;
1332       case 1:
1333         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
1334         reg4 = c_x2-reg1;
1335         yy2 = c_y1 + c_dy*(reg2-reg1)/reg4;
1336         xx2 = reg2;
1337         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
1338         break;
1339       case 2:
1340         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
1341         reg4 = c_x2-reg1;
1342         yy2 = c_y1 + c_dy*(reg2-reg1)/reg4;
1343         xx2 = reg2;
1344         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
1345         break;
1346       case 3:
1347         reg1 = c_y1; reg2 = Nlm_stCon.ymax;
1348         reg4 = c_y2-reg1;
1349         xx2 = c_x1 + c_dx*(reg2-reg1)/reg4;
1350         yy2 = reg2;
1351         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
1352         break;
1353       case 4:
1354         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
1355         reg4 = c_x2-reg1;
1356         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1357         yy2 = reg3;
1358         xx2 = reg2;
1359         if ( (reg3 < Nlm_stCon.ymin) || (reg3 > Nlm_stCon.ymax) ) {
1360           reg1 = c_y1; reg2 = Nlm_stCon.ymax;
1361           reg4 = c_y2-reg1;
1362           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1363           xx2 = reg3;
1364           yy2 = reg2;
1365         }
1366         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
1367         break;
1368       case 5:
1369         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
1370         reg4 = c_x2-reg1;
1371         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1372         yy2 = reg3;
1373         xx2 = reg2;
1374         if ( (reg3 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
1375           reg1 = c_y1; reg2 = Nlm_stCon.ymax;
1376           reg4 = c_y2-reg1;
1377           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1378           xx2 = reg3;
1379           yy2 = reg2;
1380         }
1381         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
1382         break;
1383       case 6:
1384         reg1 = c_y1; reg2 = Nlm_stCon.ymin;
1385         reg4 = c_y2-reg1;
1386         xx2 = c_x1 + c_dx*(reg2-reg1)/reg4;
1387         yy2 = reg2;
1388         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
1389         break;
1390       case 7:
1391         reg1 = c_x1; reg2 = Nlm_stCon.xmin;
1392         reg4 = c_x2-reg1;
1393         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1394         yy2 = reg3;
1395         xx2 = reg2;
1396         if ( (reg3 < Nlm_stCon.ymin) || (reg3 > Nlm_stCon.ymax) ) {
1397           reg1 = c_y1; reg2 = Nlm_stCon.ymin;
1398           reg4 = c_y2-reg1;
1399           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1400           xx2 = reg3;
1401           yy2 = reg2;
1402         }
1403         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
1404         break;
1405       default:
1406         reg1 = c_x1; reg2 = Nlm_stCon.xmax;
1407         reg4 = c_x2-reg1;
1408         reg3 = c_y1 + c_dy*(reg2-reg1)/reg4;
1409         yy2 = reg3;
1410         xx2 = reg2;
1411         if ( (reg3 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
1412           reg1 = c_y1; reg2 = Nlm_stCon.ymin;
1413           reg4 = c_y2-reg1;
1414           reg3 = c_x1 + c_dx*(reg2-reg1)/reg4;
1415           xx2 = reg3;
1416           yy2 = reg2;
1417         }
1418         zz2 = c_z1 + c_dz*(reg2-reg1)/reg4;
1419     }
1420     if ( (xx1==xx2) && (yy1==yy2) ) {
1421       reg1 = rad;
1422       Nlm_stCon.xmin += reg1;
1423       Nlm_stCon.xmax -= reg1; 
1424       Nlm_stCon.ymin += reg1;
1425       Nlm_stCon.ymax -= reg1; 
1426       return;
1427     }
1428   } else {
1429     yy1 = c_y1; yy2 = c_y2;
1430     xx1 = c_x1; xx2= c_x2;
1431     zz1= c_z1; zz2 = c_z2;
1432   }
1433   reg3 = xx1;
1434   reg4 = xx2;
1435   if ( reg3 < reg4 ) {
1436     if ( (reg3 < Nlm_stCon.xmin)||(reg4 > Nlm_stCon.xmax) ) {
1437       reg1 = rad;
1438       Nlm_stCon.xmin += reg1;
1439       Nlm_stCon.xmax -= reg1; 
1440       Nlm_stCon.ymin += reg1;
1441       Nlm_stCon.ymax -= reg1; 
1442       return;
1443     }
1444     reg1 = 0;
1445   } else {
1446     if ( (reg4 < Nlm_stCon.xmin)||(reg3 > Nlm_stCon.xmax) ) {
1447       reg1 = rad;
1448       Nlm_stCon.xmin += reg1;
1449       Nlm_stCon.xmax -= reg1; 
1450       Nlm_stCon.ymin += reg1;
1451       Nlm_stCon.ymax -= reg1;
1452       return;
1453     }
1454     reg1 = 1;
1455   }
1456   reg3 = yy1;
1457   reg4 = yy2;
1458   if ( reg3 < reg4 ) {
1459     if ( (reg3 < Nlm_stCon.ymin)||(reg4 > Nlm_stCon.ymax) ) {
1460       reg1 = rad;
1461       Nlm_stCon.xmin += reg1;
1462       Nlm_stCon.xmax -= reg1; 
1463       Nlm_stCon.ymin += reg1;
1464       Nlm_stCon.ymax -= reg1; 
1465       return;
1466     }
1467   } else {
1468     if ( (reg4 < Nlm_stCon.ymin)||(reg3 > Nlm_stCon.ymax) ) {
1469       reg1 = rad;
1470       Nlm_stCon.xmin += reg1;
1471       Nlm_stCon.xmax -= reg1; 
1472       Nlm_stCon.ymin += reg1;
1473       Nlm_stCon.ymax -= reg1; 
1474       return;
1475     }
1476     reg1 |= 0x2;
1477   }
1478   orient = reg1;
1479   reg1 = rad;
1480   Nlm_stCon.xmin += reg1;
1481   Nlm_stCon.xmax -= reg1; 
1482   Nlm_stCon.ymin += reg1;
1483   Nlm_stCon.ymax -= reg1;
1484 
1485   /* Calculate offsets and pointers */
1486   reg1 = (yy1-Nlm_stCon.ymin) * Nlm_stCon.widthCur + (xx1-Nlm_stCon.xmin);
1487   offset1 = reg1;
1488   reg3 = (long)(Nlm_stCon.idBuffer + reg1);
1489   reg2 = (yy2-Nlm_stCon.ymin) * Nlm_stCon.widthCur + (xx2-Nlm_stCon.xmin);
1490   offset2 = reg2;
1491   reg4 = (long)(Nlm_stCon.idBuffer + reg2);
1492   /* reg3 - statrt reg4 - end */
1493 
1494   /* Will be:
1495      reg1 - last orientation
1496      reg2 - zz1
1497      reg3 - start
1498      reg4 - zPtr
1499      endPtr saved in endPtr */
1500   reg1 = orient;
1501   switch ( reg1 ){
1502     case 0:
1503       dy = yy2 - yy1;
1504       reg2 = xx2 - xx1;
1505       dx = reg2;
1506       if ( reg2>dy ) {
1507         zrate = ((zz2 - zz1)<<10)/reg2;
1508       } else {
1509         zrate = ((zz2 - zz1)<<10)/dy;
1510         reg1 = 2;
1511       }
1512       reg2 = zz1;
1513       endPtr = reg4;
1514       arc_xmin = Nlm_stCon.xmin - xx1;
1515       arc_xmax = Nlm_stCon.xmax - xx1;
1516       arc_ymin = Nlm_stCon.ymin - yy1;
1517       arc_ymax = Nlm_stCon.ymax - yy1;
1518       reg4 = (long)(Nlm_stCon.zBuffer + offset1);
1519       break;
1520     case 1:
1521       dy = yy2 - yy1;
1522       reg2 = xx1 - xx2;
1523       if ( reg2 > dy ) {
1524         zrate = ((zz1 - zz2)<<10)/reg2;
1525       } else {
1526         zrate = ((zz1 - zz2)<<10)/dy;
1527         reg1 = 3;
1528       }
1529       dx = reg2;
1530       reg2 = reg3; reg3 = reg4; reg4 = reg2;
1531       reg2 = zz2;
1532       endPtr = reg4;
1533       arc_xmin = Nlm_stCon.xmin - xx2;
1534       arc_xmax = Nlm_stCon.xmax - xx2;
1535       arc_ymin = Nlm_stCon.ymin - yy2;
1536       arc_ymax = Nlm_stCon.ymax - yy2;
1537       reg4 = (long)(Nlm_stCon.zBuffer + offset2);
1538       break;
1539     case 2:
1540       dy = yy1 - yy2;
1541       reg2 = xx2 - xx1;
1542       if ( reg2 > dy ){
1543         zrate = ((zz2 - zz1)<<10)/reg2;
1544         reg1 = 1;
1545       } else {
1546         zrate = ((zz2 - zz1)<<10)/dy;
1547         reg1 = 3;
1548       }
1549       dx = reg2;
1550       reg2 = zz1;
1551       endPtr = reg4;
1552       arc_xmin = Nlm_stCon.xmin - xx1;
1553       arc_xmax = Nlm_stCon.xmax - xx1;
1554       arc_ymin = Nlm_stCon.ymin - yy1;
1555       arc_ymax = Nlm_stCon.ymax - yy1;
1556       reg4 = (long)(Nlm_stCon.zBuffer + offset1);
1557       break;
1558     default:
1559       dy = yy1 - yy2;
1560       reg2 = xx1 - xx2;
1561       if ( reg2 > dy ){
1562         zrate = ((zz1 - zz2)<<10)/reg2;
1563         reg1 = 0;
1564       } else {
1565         zrate = ((zz1 - zz2)<<10)/dy;
1566         reg1 = 2;
1567       }
1568       dx = reg2;
1569       reg2 = reg3; reg3 = reg4; reg4 = reg2;
1570       reg2 = zz2;
1571       endPtr = reg4;
1572       arc_xmin = Nlm_stCon.xmin - xx2;
1573       arc_xmax = Nlm_stCon.xmax - xx2;
1574       arc_ymin = Nlm_stCon.ymin - yy2;
1575       arc_ymax = Nlm_stCon.ymax - yy2;
1576       reg4 = (long)(Nlm_stCon.zBuffer + offset2);
1577   }
1578 
1579   SETARCPIXELID(reg4,reg3,reg2,p);
1580   reg2 <<= 10;
1581   /* Will be: reg1 - err */
1582   switch ( reg1 ){
1583     case 0:
1584       reg1 = -(dx>>1);
1585       do {
1586         reg1 += dy;
1587         if ( reg1 > 0 ){
1588            reg3 += ystep; 
1589            arc_ymin--;
1590            arc_ymax--;
1591            reg4 += zystep; 
1592            reg1 -= dx; 
1593         }
1594         reg3 += sizeof(Nlm_stCon.idBuffer[0]); reg4++; reg4++;
1595         arc_xmin--;
1596         arc_xmax--;
1597         reg2 += zrate; 
1598         curz = reg2;
1599         reg2 >>= 10;
1600         SETARCPIXELID(reg4,reg3,reg2,p);
1601         reg2 = curz;
1602       } while ( reg3 != endPtr );
1603       break;
1604     case 1:
1605       reg1 = -(dx>>1);
1606       do {
1607         reg1 += dy;
1608         if ( reg1 > 0 ){
1609            reg3 -= ystep; 
1610            arc_ymin++;
1611            arc_ymax++;
1612            reg4 -= zystep; 
1613            reg1 -= dx; 
1614         }
1615         reg3 += sizeof(Nlm_stCon.idBuffer[0]); reg4++; reg4++;
1616         arc_xmin--;
1617         arc_xmax--;
1618         reg2 += zrate; 
1619         curz = reg2;
1620         reg2 >>= 10;
1621         SETARCPIXELID(reg4,reg3,reg2,p);
1622         reg2 = curz;
1623       } while ( reg3 != endPtr );
1624       break;
1625     case 2:
1626       reg1 = -(dy>>1);
1627       do {
1628         reg1 += dx;
1629         if ( reg1 > 0 ) {
1630            reg3 += sizeof(Nlm_stCon.idBuffer[0]);
1631            arc_xmin--;
1632            arc_xmax--;
1633            reg4 ++; reg4++;
1634            reg1 -= dy; 
1635         }
1636         reg3 += ystep; 
1637         arc_ymin--;
1638         arc_ymax--;
1639         reg4 += zystep; 
1640         reg2 += zrate; 
1641         curz = reg2;
1642         reg2 >>= 10;
1643         SETARCPIXELID(reg4,reg3,reg2,p);
1644         reg2 = curz;
1645       } while ( reg3 != endPtr );
1646       break;
1647     default:
1648       reg1 = -(dy>>1);
1649       do {
1650         reg1 += dx;
1651         if ( reg1 > 0 ) {
1652            reg3 += sizeof(Nlm_stCon.idBuffer[0]);
1653            arc_xmin--;
1654            arc_xmax--;
1655            reg4++; reg4++;
1656            reg1 -= dy; 
1657         }
1658         reg3 -= ystep; 
1659         arc_ymin++;
1660         arc_ymax++;
1661         reg4 -= zystep; 
1662         reg2 += zrate; 
1663         curz = reg2;
1664         reg2 >>= 10;
1665         SETARCPIXELID(reg4,reg3,reg2,p);
1666         reg2 = curz;
1667       } while ( reg3 != endPtr );
1668   }
1669 }
1670 
1671 static void Nlm_Cylin3DGetL ( Nlm_Cylin3DPtr p )
1672 {
1673   register BigScalar ax;
1674   register BigScalar bx;
1675   long minXY, maxXY;
1676 
1677   ax = (BigScalar)p;
1678   bx = (BigScalar)(((Nlm_PSeg3DPtr)ax)->base.parent);
1679   if ( ((Nlm_Cylin3DPtr)ax)->x1 > ((Nlm_Cylin3DPtr)ax)->x2 ){
1680     maxXY = ((Nlm_Cylin3DPtr)ax)->x1; minXY = ((Nlm_Cylin3DPtr)ax)->x2;
1681   } else {
1682     maxXY = ((Nlm_Cylin3DPtr)ax)->x2; minXY = ((Nlm_Cylin3DPtr)ax)->x1;
1683   }
1684   maxXY += ((Nlm_Cylin3DPtr)ax)->radius;
1685   minXY -= ((Nlm_Cylin3DPtr)ax)->radius;
1686   if ( ((Nlm_PSeg3DPtr)bx)->segBox.minX > minXY )
1687        ((Nlm_PSeg3DPtr)bx)->segBox.minX = minXY;
1688   if ( ((Nlm_PSeg3DPtr)bx)->segBox.maxX < maxXY )
1689        ((Nlm_PSeg3DPtr)bx)->segBox.maxX = maxXY;
1690   if ( ((Nlm_Cylin3DPtr)ax)->y1 > ((Nlm_Cylin3DPtr)ax)->y2 ){
1691     maxXY = ((Nlm_Cylin3DPtr)ax)->y1; minXY = ((Nlm_Cylin3DPtr)ax)->y2;
1692   } else {
1693     maxXY = ((Nlm_Cylin3DPtr)ax)->y2; minXY = ((Nlm_Cylin3DPtr)ax)->y1;
1694   }
1695   maxXY += ((Nlm_Cylin3DPtr)ax)->radius;
1696   minXY -= ((Nlm_Cylin3DPtr)ax)->radius;
1697   if ( ((Nlm_PSeg3DPtr)bx)->segBox.minY > minXY )
1698        ((Nlm_PSeg3DPtr)bx)->segBox.minY = minXY;
1699   if ( ((Nlm_PSeg3DPtr)bx)->segBox.maxY < maxXY )
1700        ((Nlm_PSeg3DPtr)bx)->segBox.maxY = maxXY;
1701   if ( ((Nlm_Cylin3DPtr)ax)->z1 > ((Nlm_Cylin3DPtr)ax)->z2 ){
1702     maxXY = ((Nlm_Cylin3DPtr)ax)->z1; minXY = ((Nlm_Cylin3DPtr)ax)->z2;
1703   } else {
1704     maxXY = ((Nlm_Cylin3DPtr)ax)->z2; minXY = ((Nlm_Cylin3DPtr)ax)->z1;
1705   }
1706   if ( ((Nlm_PSeg3DPtr)bx)->segBox.minZ > minXY )
1707        ((Nlm_PSeg3DPtr)bx)->segBox.minZ = minXY;
1708   if ( ((Nlm_PSeg3DPtr)bx)->segBox.maxZ < maxXY )
1709        ((Nlm_PSeg3DPtr)bx)->segBox.maxZ = maxXY;
1710 }
1711 
1712 static Nlm_PrimDef3D cylinDef = {
1713   (Nlm_PrimDraw3D)Nlm_Cylin3DDraw,
1714   (Nlm_PrimHitTest3D)Nlm_Cylin3DHitT,
1715   (Nlm_PrimGetLimits3D)Nlm_Cylin3DGetL,
1716   (Nlm_PrimCleanup3D)Nlm_Empty3D,
1717   (Nlm_Int2)LINE3D
1718 };
1719 
1720 Nlm_Prim3D Nlm_AddCylinder3D ( Nlm_Picture3D pic, Nlm_Segment3D segment, 
1721                                BigScalar userData, Uint1 layer, Uint1 color,
1722                                Int4 x1, Int4 y1, Int4 z1,
1723                                Int4 x2, Int4 y2, Int4 z2, Uint4 radius )
1724 {
1725   Nlm_Cylin3D l;
1726 
1727   Nlm_stCon.pic = pic;
1728   Nlm_DiagReset ();
1729   l.base.userData = userData;
1730   l.base.layer = layer;
1731   l.base.color = color;
1732   l.base.fTable = &cylinDef;
1733   l.base.status = 0;
1734   l.x1 = (long)x1; l.x2 = (long)x2;
1735   l.y1 = (long)y1; l.y2 = (long)y2;
1736   l.z1 = (long)z1; l.z2 = (long)z2;
1737   l.radius = (long)radius;
1738   return (Nlm_Prim3D) Nlm_AddPrim3D ( (Nlm_PSeg3DPtr)segment, 
1739                                       (Nlm_Base3DPtr)&l,
1740                                       sizeof(Nlm_Cylin3D), 
1741                                       "AddCylin3D" );
1742 }
1743 
1744 
1745 

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.