void DoSlewingMenu( int *menu ) // Shows slew progress in X and Y. Called to do the slew from within // the tracking routine, and returns to tracking when done. { long int X_Target, Y_Target; double HA, Alt, Az; int x=25, y=TRACKINGDISPLAY, w=y+5; clrscr(); FrameScreen(); *menu = TrackingMenu; gotoxy(37,y); printf("Slewing"); DisplayCoordinates(w,1,1,0); gotoxy(x,w+0); printf("(Target RA: %4d:%02d:%02d )", _HOURS(RA_Target), _MINUTES(RA_Target), _SECONDS(RA_Target)); gotoxy(x,w+1); printf("(Target Dec:%+4d:%02d:%02d )", _SIGN(DecTarget)*_HOURS(DecTarget), _MINUTES(DecTarget), _SECONDS(DecTarget)); gotoxy(18,w+6); printf("Hit q to stop slewing and return to tracking."); PrevStatus = Status; Status = SLEWING; do { Slew(w+2); GetXY( RA_Target, DecTarget, &X_Target, &Y_Target ); dX = X_Target - gX; dY = Y_Target - gY; } while ( (pow(dX,2)+pow(dY,2)) > pow(CLOSE_ENOUGH,2) ); PrevStatus = Status; Status = TRACKING; }
void Slew( int y_display ) // Using the global variables dX and dY as the distances to go in X and Y, // this routine sends out pulses to the motors to move the telescope the // required distance. dX and dY are in "steps" of the motors. This routine // sends a stream of pulses to the motors, ramping them up to the cruising // speed, and ramping them down to zero when finished. It also checks if the // flag indicating the user wants to abort the slew has been set, and if so // ramps down the motors to zero immediately. Although it slows down the // process a little, this routine also continually updates the coordinates // on the screen so the user can see how far along the slew is. { long int flag=1, outword; long int L2=LEVELS*2, xskip[LEVELS*2+1], yskip[LEVELS*2+1]; long int x_skip, y_skip; long int xsend[LEVELS*2+1], ysend[LEVELS*2+1], i, j, total, i2; long int x_cruise_index, y_cruise_index, X, Y, X2, Y2, common; long int xtemp=0L, ytemp=0L; int quit=0, Xout, Yout; int xloop=5, yloop=5; x_sign = _SIGN(dX); y_sign = _SIGN(dY); cumulative[0] = MinSteps; for (i=0; i<LEVELS; i++) { common = MinSteps + i*(MaxSteps-MinSteps)/LEVELS; // ramp up from xsend[i] = common; xsend[L2-i] = common; // MinSteps and ysend[i] = common; ysend[L2-i] = common; // MaxDelay... common = MaxDelay - i*(MaxDelay-MinDelay)/LEVELS; xskip[i] = common; xskip[L2-i] = common; yskip[i] = common; yskip[L2-i] = common; // to MaxSteps if (i) cumulative[i] = cumulative[i-1] + xsend[i]; // and MinDelay. } xsend[LEVELS] = 0; ysend[LEVELS] = 0; cumulative[LEVELS] = cumulative[LEVELS-1]; xskip[LEVELS] = MinDelay; yskip[LEVELS] = MinDelay; // for (i=0;i<=L2;i++) printf(" xskip[%ld]=%ld",i,xskip[i]); total=0; i=0; X2 = labs(dX)/2; while ((total+xsend[i])<X2 && i<LEVELS) total += xsend[i++]; x_cruise_index = i; // gotoxy(2,2); printf("x_cruise_index = %ld", x_cruise_index); i2 = 2*i; for (i=x_cruise_index+1; i<=i2; i++) { xskip[i] = xskip[i2-i]; xsend[i] = xsend[i2-i]; total += xsend[i]; } if (total < labs(dX)) xsend[x_cruise_index] = labs(dX) - total; else xsend[x_cruise_index] = 0; // gotoxy(2,3); printf("xsend[%ld] = %ld, xskip[%ld] = %ld", x_cruise_index, // xsend[x_cruise_index], x_cruise_index, xskip[x_cruise_index] ); total=0; i=0; Y2 = labs(dY)/2; while ((total+ysend[i])<Y2 && i<LEVELS) total += ysend[i++]; y_cruise_index = i; i2 = 2*i; for (i=y_cruise_index+1; i<=i2; i++) { yskip[i] = yskip[i2-i]; ysend[i] = ysend[i2-i]; total += ysend[i]; } if (total < labs(dY)) ysend[y_cruise_index] = labs(dY) - total; else ysend[y_cruise_index] = 0; i=0; j=0; x_skip = xskip[0]; y_skip = yskip[0]; gotoxy(37,y_display); printf("%+9ld ", gX); if (!dX) printf(" "); gotoxy(37,y_display+1); printf("%+9ld ", gY); if (!dY) printf(" "); while (flag) { Xout=0; Yout=0; if (dX) { if ((--x_skip) == 0) { X = x_sign; if (X<0) Xout = XMINUS; else Xout = X*XPLUS; dX -= X; // xtemp++; if ((--xsend[i]) == 0) ++i; x_skip = xskip[i]; } else X = 0; } else X = 0; if (dY) { if ((--y_skip) == 0) { Y = y_sign; if (Y<0) Yout = YMINUS; else Yout = Y*YPLUS; dY -= Y; // ytemp++; if ((--ysend[j]) == 0) ++j; y_skip = yskip[j]; } else Y = 0; } else Y = 0; outword = NOPULSE - Xout - Yout; outp( PULSEPORT, outword ); gX += X; gY += Y; if (Xout || Yout) { if (Xout) { if (++xloop>2) { xloop=0; gotoxy(38,y_display); printf("%+9ld ", gX); // printf(" i=%3ld, xsend[i]=%ld, xskip[i]=%ld ", i, xsend[i], xskip[i]); if (!dX) printf(" "); } } if (Yout) { if (++yloop>2) { yloop=0; gotoxy(38,y_display+1); printf("%+9ld ", gY); if (!dY) printf(" "); } } } if (!(dX || dY)) flag=0; // dX=0 and dY=0 => done slewing if (abort_slew_flag) { quit = 1; if (i<=x_cruise_index) { if (i==x_cruise_index) dX = x_sign * cumulative[i++]; else { dX = x_sign * cumulative[i]; i = 2*x_cruise_index - i; } } if (j<=y_cruise_index) { if (j==y_cruise_index) dY = y_sign * cumulative[j++]; else { dY = y_sign * cumulative[j]; j = 2*y_cruise_index - j; } } abort_slew_flag = 0; gotoxy(46,y_display); if (dX) printf(" (ramping down)"); else printf(" "); gotoxy(46,y_display+1); if (dY) printf(" (ramping down)"); else printf(" "); } outp( PULSEPORT, NOPULSE ); } // while (flag) if (quit) // if the user requested the slew be aborted, we'll take up { // tracking on wherever we landed out of the slew. GetRADec( gX, gY, &RA_Target, &DecTarget ); } }
/* * We try and clip a curve so that it can be either Case A, or Case C. * Sometimes one of the curves is still case C though, but it is much * small than the original, and further clipping will either show that * it is on the curve or provide all Case B or Case A curves. * We try and pick the best axis to clip against, but this may not always * work. One extra step that was included, that is not in the paper for * curves but is for surfaces, is the fact that sometimes the curve is * not clipped enough, if the maximum clip is less than .2 than we sub * divide the curve in three equal parts, at .3 and .6, * Subdivision is done using the Oslo Algorithm, rather than the other * methods which were prossed. */ void rt_clip_cnurb(struct bu_list *plist, struct edge_g_cnurb *crv, fastf_t u, fastf_t v) { fastf_t ds1, dt1; struct _interior_line s_line, t_line; int axis, i; fastf_t umin, umax; int coords; struct edge_g_cnurb * c1, *c2, *tmp; fastf_t m1, m2; int zero_changed; fastf_t *ptr; fastf_t dist[10]; coords = RT_NURB_EXTRACT_COORDS( crv->pt_type); s_line.axis = 0; s_line.o_dist = v; t_line.axis = 1; t_line.o_dist = u; ds1 = 0.0; dt1 = 0.0; ptr = crv->ctl_points; /* determine what axis to clip against */ for ( i = 0; i < crv->c_size; i++, ptr += coords) { ds1 += fabs( rt_trim_line_pt_dist( &s_line, ptr, crv->pt_type) ); dt1 += fabs( rt_trim_line_pt_dist( &t_line, ptr, crv->pt_type) ); } if ( ds1 >= dt1 ) axis = 0; else axis = 1; ptr = crv->ctl_points; for ( i = 0; i < crv->c_size; i++) { if ( axis == 1) dist[i] = rt_trim_line_pt_dist(&t_line, ptr, crv->pt_type); else dist[i] = rt_trim_line_pt_dist(&s_line, ptr, crv->pt_type); ptr += coords; } /* Find the convex hull of the distances and determine the * minimum and maximum distance to clip against. See the * paper for details about this step */ umin = 10e40; umax = -10e40; zero_changed = 0; for ( i = 0; i < crv->c_size; i++) { fastf_t d1, d2; fastf_t x0, x1, zero; if ( i == (crv->c_size -1 ) ) { d1 = dist[i]; d2 = dist[0]; x0 = (fastf_t) i / (fastf_t) (crv->c_size - 1); x1 = 0.0; } else { d1 = dist[i]; d2 = dist[i+1]; x0 = (fastf_t) i / (fastf_t) (crv->c_size - 1 ); x1 = (i+1.0) / (crv->c_size - 1); } if ( _SIGN(d1) != _SIGN(d2) ) { zero = x0 - d1 * (x1 - x0)/ (d2-d1); if ( zero <= umin) umin = zero * .99; if ( zero >= umax) umax = zero * .99 + .01; zero_changed = 1; } } if ( !zero_changed) return; /* Clip is not large enough, split in thiords and try again */ if ( umax - umin < .2) { umin = .3; umax = .6; } /* Translate the 0.0-->1.09 clipping against the real knots */ m1 = (crv->k.knots[0] * (1 - umin)) + crv->k.knots[crv->k.k_size -1] * umin; m2 = (crv->k.knots[0] * (1-umax)) + crv->k.knots[crv->k.k_size -1] * umax; /* subdivide the curve */ c1 = (struct edge_g_cnurb *) rt_nurb_c_xsplit(crv, m1); c2 = rt_nurb_c_xsplit((struct edge_g_cnurb *) c1->l.forw, m2); tmp = (struct edge_g_cnurb *) c1->l.forw; BU_LIST_DEQUEUE( &tmp->l); rt_nurb_free_cnurb( tmp ); BU_LIST_INIT( plist ); BU_LIST_INSERT( &c2->l, plist); BU_LIST_APPEND( plist, &c1->l); }