Пример #1
0
// Start a move to the value setpoint:
AMControl::FailureExplanation CLSMDriveMotorControl::move(double Setpoint) {

    if(isMoving()) {
        if(!allowsMovesWhileMoving()) {
            AMErrorMon::debug(this, AMPVCONTROL_COULD_NOT_MOVE_WHILE_MOVING, QString("AMPVControl: Could not move %1 (%2) to %3, because the control is already moving.").arg(name()).arg(writePV_->pvName()).arg(setpoint_));
            return AlreadyMovingFailure;
        }

        if(!moveInProgress()) {
            // the control is already moving, but it's not one of our moves. In this situation, there is no way that we can start a move and be assured that we'll be notified when OUR move finishes.
            AMErrorMon::debug(this, AMPVCONTROL_COULD_NOT_MOVE_WHILE_MOVING_EXTERNAL, QString("AMPVControl: Could not move %1 (%2) to %3, because the control is already moving.").arg(name()).arg(writePV_->pvName()).arg(setpoint_));
            return AlreadyMovingFailure;
        }

        // Otherwise: This control supports mid-move updates, and we're already moving. We just need to update the setpoint and send it.
        setpoint_ = writeUnitConverter()->convertToRaw(Setpoint);
        writePV_->setValue(setpoint_);
        // since the settling phase is considered part of a move, it's OK to be here while settling... But for Acquaman purposes, this will be considered a single re-targetted move, even though the hardware will see two.  If we're settling, disable the settling timer, because we only want to respond to the end of the second move.
        if(settlingInProgress_) {
            settlingInProgress_ = false;
            settlingTimer_.stop();
        }
        emit moveReTargetted(); // re-targetted moves will emit moveReTargetted(), although no moveSucceeded()/moveFailed() will be issued for the initial move.
    }

    else {
        settlingInProgress_ = false;
        stopInProgress_ = false;
        moveInProgress_ = false;
        // Flag that "our" move started:
        startInProgress_ = true;

        // This is our new target:
        setpoint_ = writeUnitConverter()->convertToRaw(Setpoint);

        // Special case: "null move" should complete immediately. Use only if moveStartTolerance() is non-zero, and the move distance is within moveStartTolerance().
        if(moveStartTolerance() != 0 && fabs(setpoint()-value()) < moveStartTolerance()) {
            startInProgress_ = false;
            moveInProgress_ = true;
            emit moveStarted();
            moveInProgress_ = false;
            emit moveSucceeded();
        }
        // Normal move:
        else {
            // Issue the move command:
            writePV_->setValue(setpoint_);
            // start the timer to check if our move failed to start:
            moveStartTimer_.start(int(moveStartTimeout_*1000.0));
        }
    }

    return NoFailure;
}
Пример #2
0
void AMPVwStatusAndUnitConversionControl::setUnitConverters(AMAbstractUnitConverter *readUnitConverter, AMAbstractUnitConverter* writeUnitConverter)
{
	double oldValue = value();
	double oldSetpoint = setpoint();

	delete readConverter_;
	readConverter_ = readUnitConverter;
	if(writeConverter_)
		delete writeConverter_;
	writeConverter_ = writeUnitConverter;

	double newValue = value();
	double newSetpoint = setpoint();

	setUnits(readConverter_->units());

	if(newValue != oldValue)
		emit valueChanged(newValue);
	if(newSetpoint != oldSetpoint)
		emit setpointChanged(newSetpoint);
}
Пример #3
0
void
plD_line_ljii(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
{
    PLDev *dev = (PLDev *) pls->dev;
    int i;
    int xx1 = x1a, yy1 = y1a, xx2 = x2a, yy2 = y2a;
    PLINT x1b, y1b, x2b, y2b;
    PLFLT length, fx, fy, dx, dy;

/* Take mirror image, since PCL expects (0,0) to be at top left */

    yy1 = dev->ymax - (yy1 - dev->ymin);
    yy2 = dev->ymax - (yy2 - dev->ymin);

/* Rotate by 90 degrees */

    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &xx1, &yy1);
    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &xx2, &yy2);

    x1b = xx1, x2b = xx2, y1b = yy1, y2b = yy2;
    length = (PLFLT) sqrt((double)
		     ((x2b - x1b) * (x2b - x1b) + (y2b - y1b) * (y2b - y1b)));

    if (length == 0.)
	length = 1.;
    dx = (xx2 - xx1) / length;
    dy = (yy2 - yy1) / length;

    fx = xx1;
    fy = yy1;
    setpoint((PLINT) xx1, (PLINT) yy1);
    setpoint((PLINT) xx2, (PLINT) yy2);

    for (i = 1; i <= (int) length; i++)
	setpoint((PLINT) (fx += dx), (PLINT) (fy += dy));
}
Пример #4
0
// This is used to handle the timeout of a move start:
void CLSMDriveMotorControl::onMoveStartTimeout() {

    moveStartTimer_.stop();

    // This is only meaningful if one of our moves is in progress.
    if(startInProgress_) {
        // give up on this move:
        startInProgress_ = false;

        // Special case: only applies if moveTimeoutTolerance_ != 0 AND we've gotten within moveTimeoutTolerance_ of the setpoint.
        if(moveTimeoutTolerance() != 0.0 && fabs(setpoint() - value()) < moveTimeoutTolerance_) {
            moveInProgress_ = true;
            emit moveStarted();
            moveInProgress_ = false;
            emit moveSucceeded();
        }
        else {
            // The move didn't start within our allowed start period. That counts as a move failed.
            emit moveFailed(AMControl::TimeoutFailure);
        }
    }
}
Пример #5
0
void* ThreadFunction2(void* port)
{
  int secondcounter = 0;
  int outtransition = 0;
  int state = (int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetPointImpl@7c26a0ba (initial: true) (point: [POINT_19, POINT_20, POINT_23, POINT_24], direction: BRANCH)"));
  
  if (DEBUGCONTROLLER) printf("Thread 'org.eclipse.internal.xpand2.type.XpandIterator@432dbb4b' started.\n");
  
  while(1) {
      if (DEBUGCONTROLLER) printf("Entering state %d.\n",state);
      
      //escape if railway system is down
      if (!railway_alive(railway)) {
	  	  if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
     	  exit(EXIT_FAILURE);
	  }//end if
	  
      //all states
      if (state == -1) {}
	  else if (state == ((int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@73b61aea (initial: false) (track: [IC_JCT_0, IC_LN_0, IC_LN_1, IC_LN_2, IC_LN_3, IC_LN_4, IC_LN_5, IC_ST_0, IC_ST_2, IC_ST_4], speed: 100, direction: FWD)")))) {
	  		  P(2); // GET THE GLOBALLOCK
              if (DEBUGCONTROLLER) printf("State %d (de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@73b61aea (initial: false) (track: [IC_JCT_0, IC_LN_0, IC_LN_1, IC_LN_2, IC_LN_3, IC_LN_4, IC_LN_5, IC_ST_0, IC_ST_2, IC_ST_4], speed: 100, direction: FWD)) entered.\n",(int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@73b61aea (initial: false) (track: [IC_JCT_0, IC_LN_0, IC_LN_1, IC_LN_2, IC_LN_3, IC_LN_4, IC_LN_5, IC_ST_0, IC_ST_2, IC_ST_4], speed: 100, direction: FWD)")));
	          //state1 entry code (SET SPEED)
			  settrack(railway, IC_JCT_0, FWD, 100);
		      setsignal(railway, IC_JCT_0, FIRST, OFF);
		      setsignal(railway, IC_JCT_0, SECOND, GREEN);
			  settrack(railway, IC_LN_0, FWD, 100);
		      setsignal(railway, IC_LN_0, FIRST, OFF);
		      setsignal(railway, IC_LN_0, SECOND, GREEN);
			  settrack(railway, IC_LN_1, FWD, 100);
		      setsignal(railway, IC_LN_1, FIRST, OFF);
		      setsignal(railway, IC_LN_1, SECOND, GREEN);
			  settrack(railway, IC_LN_2, FWD, 100);
		      setsignal(railway, IC_LN_2, FIRST, OFF);
		      setsignal(railway, IC_LN_2, SECOND, GREEN);
			  settrack(railway, IC_LN_3, FWD, 100);
		      setsignal(railway, IC_LN_3, FIRST, OFF);
		      setsignal(railway, IC_LN_3, SECOND, GREEN);
			  settrack(railway, IC_LN_4, FWD, 100);
		      setsignal(railway, IC_LN_4, FIRST, OFF);
		      setsignal(railway, IC_LN_4, SECOND, GREEN);
			  settrack(railway, IC_LN_5, FWD, 100);
		      setsignal(railway, IC_LN_5, FIRST, OFF);
		      setsignal(railway, IC_LN_5, SECOND, GREEN);
			  settrack(railway, IC_ST_0, FWD, 100);
		      setsignal(railway, IC_ST_0, FIRST, OFF);
		      setsignal(railway, IC_ST_0, SECOND, GREEN);
			  settrack(railway, IC_ST_2, FWD, 100);
		      setsignal(railway, IC_ST_2, FIRST, OFF);
		      setsignal(railway, IC_ST_2, SECOND, GREEN);
			  settrack(railway, IC_ST_4, FWD, 100);
		      setsignal(railway, IC_ST_4, FIRST, OFF);
		      setsignal(railway, IC_ST_4, SECOND, GREEN);
	  		  V(2); // RELEASE THE GLOBALLOCK
	  		  
	          
	          //state1 transitions code
	          secondcounter = 0;
	          while(1) {
		   		    P(2); // GET THE GLOBALLOCK
	                outtransition = 0;
		            if ((DEBUGCONTROLLER)&&(!(secondcounter%10))) printf("Transition wait (%d seconds).\n",secondcounter/10);
			  		outtransition = 1;
	          		//test for contact-events
			  		if ((getcontact_sync(railway,IC_ST_2,FIRST,1) != 0)) {
			  		    V(2); // RELEASE THE GLOBALLOCK
	 	                if (DEBUGCONTROLLER) printf("Event-Transition taken.\n");
			  			state = HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@2af590c6 (initial: false) (track: [IC_ST_0, IC_ST_2], speed: 30, direction: FWD)");
			  			break;
			  		}
	  		  		V(2); // RELEASE THE GLOBALLOCK
			  			          		
	                //escape if railway system is down
                    if (!railway_alive(railway)) {
	 	                if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
				    	exit(EXIT_FAILURE);
                    }//end if
                    	          
                    //escape if not outtransitions
                    if (!outtransition) {
	 	                if (DEBUGCONTROLLER) printf("Final state - terminating thread.\n");
						//set localTERMINATED := 1 (so that we not wait on this thread in any next macro-tick any more)
		          		localTERMINATED2 = 1;   
						return (void *)1;
                    }//end if
                    	          
	          		secondcounter++;
				usleep(100000); // sleep for 100ms
					
					//set localLOCK := 1 and wait for its reset
	          		localLOCK2 = 1;   
	          		while (localLOCK2 == 1){
		                    if (!railway_alive(railway)) {
	 			                if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
						    	exit(EXIT_FAILURE);
                    		}//end if
							usleep(5000); // sleep for 5ms
							//if (DEBUGCONTROLLER) printf("Thread 2 waiting for next tick.\n");
	          		}//end while
	          		
	          }//end while
	      }//end if
	      
	  else if (state == ((int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetPointImpl@7c26a0ba (initial: true) (point: [POINT_19, POINT_20, POINT_23, POINT_24], direction: BRANCH)")))) {
	  		  P(2); // GET THE GLOBALLOCK
              if (DEBUGCONTROLLER) printf("State %d (de.cau.cs.kieler.simplerailctrl.impl.SetPointImpl@7c26a0ba (initial: true) (point: [POINT_19, POINT_20, POINT_23, POINT_24], direction: BRANCH)) entered.\n",(int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetPointImpl@7c26a0ba (initial: true) (point: [POINT_19, POINT_20, POINT_23, POINT_24], direction: BRANCH)")));
	          //state2 enty code (SET POINT)
			  setpoint(railway,  POINT_19, BRANCH);
			  setpoint(railway,  POINT_20, BRANCH);
			  setpoint(railway,  POINT_23, BRANCH);
			  setpoint(railway,  POINT_24, BRANCH);
	  		  V(2); // RELEASE THE GLOBALLOCK
	  		  
	          
	          //state2 transitions code
	          secondcounter = 0;
	          while(1) {
		   		    P(2); // GET THE GLOBALLOCK
	                outtransition = 0;
		            if ((DEBUGCONTROLLER)&&(!(secondcounter%10))) printf("Transition wait (%d seconds).\n",secondcounter/10);
			  		outtransition = 1;
	          		//test for wait-events
			  		if (secondcounter/10 >= 5) {
			  		    V(2); // RELEASE THE GLOBALLOCK
	 	                if (DEBUGCONTROLLER) printf("Wait-Transition taken.\n");
			  			state = HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@73b61aea (initial: false) (track: [IC_JCT_0, IC_LN_0, IC_LN_1, IC_LN_2, IC_LN_3, IC_LN_4, IC_LN_5, IC_ST_0, IC_ST_2, IC_ST_4], speed: 100, direction: FWD)");
			  			break;
			  		}
			  		
	  		  		V(2); // RELEASE THE GLOBALLOCK
			  			          		
	                //escape if railway system is down
                    if (!railway_alive(railway)) {
	 	                if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
				    	exit(EXIT_FAILURE);
                    }//end if
                    	          
                    //escape if not outtransitions
                    if (!outtransition) {
	 	                if (DEBUGCONTROLLER) printf("Final state - terminating thread.\n");
						//set localTERMINATED := 1 (so that we not wait on this thread in any next macro-tick any more)
		          		localTERMINATED2 = 1;   
						return (void *)1;
                    }//end if
                    	          
	          		secondcounter++;
				usleep(100000); // sleep for 100ms
					
					//set localLOCK := 1 and wait for its reset
	          		localLOCK2 = 1;   
	          		while (localLOCK2 == 1){
		                    if (!railway_alive(railway)) {
	 			                if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
						    	exit(EXIT_FAILURE);
                    		}//end if
							usleep(5000); // sleep for 5ms
							//if (DEBUGCONTROLLER) printf("Thread 2 waiting for next tick.\n");
	          		}//end while
	          		
	          }//end while
	      }//end if
	      
	  else if (state == ((int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@2af590c6 (initial: false) (track: [IC_ST_0, IC_ST_2], speed: 30, direction: FWD)")))) {
	  		  P(2); // GET THE GLOBALLOCK
              if (DEBUGCONTROLLER) printf("State %d (de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@2af590c6 (initial: false) (track: [IC_ST_0, IC_ST_2], speed: 30, direction: FWD)) entered.\n",(int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@2af590c6 (initial: false) (track: [IC_ST_0, IC_ST_2], speed: 30, direction: FWD)")));
	          //state3 entry code (SET SPEED)
			  settrack(railway, IC_ST_0, FWD, 30);
		      setsignal(railway, IC_ST_0, FIRST, OFF);
		      setsignal(railway, IC_ST_0, SECOND, YELLOW);
			  settrack(railway, IC_ST_2, FWD, 30);
		      setsignal(railway, IC_ST_2, FIRST, OFF);
		      setsignal(railway, IC_ST_2, SECOND, YELLOW);
	  		  V(2); // RELEASE THE GLOBALLOCK
	  		  
	          
	          //state3 transitions code
	          secondcounter = 0;
	          while(1) {
		   		    P(2); // GET THE GLOBALLOCK
	                outtransition = 0;
		            if ((DEBUGCONTROLLER)&&(!(secondcounter%10))) printf("Transition wait (%d seconds).\n",secondcounter/10);
			  		outtransition = 1;
	          		//test for contact-events
			  		if ((getcontact_sync(railway,IC_ST_2,SECOND,1) != 0)) {
			  		    V(2); // RELEASE THE GLOBALLOCK
	 	                if (DEBUGCONTROLLER) printf("Event-Transition taken.\n");
			  			state = HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@5ff3cd32 (initial: false) (track: [IC_ST_2], speed: 0, direction: FWD)");
			  			break;
			  		}
	  		  		V(2); // RELEASE THE GLOBALLOCK
			  			          		
	                //escape if railway system is down
                    if (!railway_alive(railway)) {
	 	                if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
				    	exit(EXIT_FAILURE);
                    }//end if
                    	          
                    //escape if not outtransitions
                    if (!outtransition) {
	 	                if (DEBUGCONTROLLER) printf("Final state - terminating thread.\n");
						//set localTERMINATED := 1 (so that we not wait on this thread in any next macro-tick any more)
		          		localTERMINATED2 = 1;   
						return (void *)1;
                    }//end if
                    	          
	          		secondcounter++;
				usleep(100000); // sleep for 100ms
					
					//set localLOCK := 1 and wait for its reset
	          		localLOCK2 = 1;   
	          		while (localLOCK2 == 1){
		                    if (!railway_alive(railway)) {
	 			                if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
						    	exit(EXIT_FAILURE);
                    		}//end if
							usleep(5000); // sleep for 5ms
							//if (DEBUGCONTROLLER) printf("Thread 2 waiting for next tick.\n");
	          		}//end while
	          		
	          }//end while
	      }//end if
	      
	  else if (state == ((int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@5ff3cd32 (initial: false) (track: [IC_ST_2], speed: 0, direction: FWD)")))) {
	  		  P(2); // GET THE GLOBALLOCK
              if (DEBUGCONTROLLER) printf("State %d (de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@5ff3cd32 (initial: false) (track: [IC_ST_2], speed: 0, direction: FWD)) entered.\n",(int)(HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@5ff3cd32 (initial: false) (track: [IC_ST_2], speed: 0, direction: FWD)")));
	          //state4 entry code (SET SPEED)
			  settrack(railway, IC_ST_2, FWD, 0);
		      setsignal(railway, IC_ST_2, FIRST, OFF);
		      setsignal(railway, IC_ST_2, SECOND, RED);
	  		  V(2); // RELEASE THE GLOBALLOCK
	  		  
	          
	          //state4 transitions code
	          secondcounter = 0;
	          while(1) {
		   		    P(2); // GET THE GLOBALLOCK
	                outtransition = 0;
		            if ((DEBUGCONTROLLER)&&(!(secondcounter%10))) printf("Transition wait (%d seconds).\n",secondcounter/10);
			  		outtransition = 1;
	          		//test for wait-events
			  		if (secondcounter/10 >= 10) {
			  		    V(2); // RELEASE THE GLOBALLOCK
	 	                if (DEBUGCONTROLLER) printf("Wait-Transition taken.\n");
			  			state = HASH("de.cau.cs.kieler.simplerailctrl.impl.SetSpeedImpl@73b61aea (initial: false) (track: [IC_JCT_0, IC_LN_0, IC_LN_1, IC_LN_2, IC_LN_3, IC_LN_4, IC_LN_5, IC_ST_0, IC_ST_2, IC_ST_4], speed: 100, direction: FWD)");
			  			break;
			  		}
			  		
	  		  		V(2); // RELEASE THE GLOBALLOCK
			  			          		
	                //escape if railway system is down
                    if (!railway_alive(railway)) {
	 	                if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
				    	exit(EXIT_FAILURE);
                    }//end if
                    	          
                    //escape if not outtransitions
                    if (!outtransition) {
	 	                if (DEBUGCONTROLLER) printf("Final state - terminating thread.\n");
						//set localTERMINATED := 1 (so that we not wait on this thread in any next macro-tick any more)
		          		localTERMINATED2 = 1;   
						return (void *)1;
                    }//end if
                    	          
	          		secondcounter++;
				usleep(100000); // sleep for 100ms
					
					//set localLOCK := 1 and wait for its reset
	          		localLOCK2 = 1;   
	          		while (localLOCK2 == 1){
		                    if (!railway_alive(railway)) {
	 			                if (DEBUGCONTROLLER) printf("Railway system down - terminating thread.\n");
						    	exit(EXIT_FAILURE);
                    		}//end if
							usleep(5000); // sleep for 5ms
							//if (DEBUGCONTROLLER) printf("Thread 2 waiting for next tick.\n");
	          		}//end while
	          		
	          }//end while
	      }//end if
	      
  }//end while
}	
Пример #6
0
void
plD_line_ljiip(PLStream *pls, short x1a, short y1a, short x2a, short y2a)
{
    PLDev *dev = (PLDev *) pls->dev;
    int xx1 = x1a, yy1 = y1a, xx2 = x2a, yy2 = y2a;
    int abs_dx, abs_dy, dx, dy, incx, incy;
    int i, j, width, residual;
    PLFLT tmp;

    width = MIN(pls->width, MAX_WID);
 
/* Take mirror image, since PCL expects (0,0) to be at top left */

    yy1 = dev->ymax - (yy1 - dev->ymin);
    yy2 = dev->ymax - (yy2 - dev->ymin);

/* Rotate by 90 degrees */

    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &xx1, &yy1);
    plRotPhy(ORIENTATION, dev->xmin, dev->ymin, dev->xmax, dev->ymax, &xx2, &yy2);

    dx = xx2 - xx1;
    dy = yy2 - yy1;

    if (dx < 0) {
	abs_dx = -dx;
	incx = -1;
    }
    else {
	abs_dx = dx;
	incx = 1;
    }
    if (dy < 0) {
	abs_dy = -dy;
	incy = -1;
    }
    else {
	abs_dy = dy;
	incy = 1;
    }

/* make pixel width narrower for diag lines */

    if (abs_dy <= abs_dx) {
	if (abs_dx == 0)
	    tmp = 1.0;
	else
	    tmp = 1.0 - (PLFLT) abs_dy / abs_dx;
    }
    else {
	tmp = 1.0 - (PLFLT) abs_dx / abs_dy;
    }

    width = floor(0.5 + width * (tmp*tmp*tmp*(1.0-0.707107) + 0.707107));

    if (width < 1) width = 1;
    if (width > 1) {
	for (i = 0; i < width; i++) {
	    for (j = 0; j < width; j++) {
	        setpoint((PLINT) (xx1+i), (PLINT) (yy1+j));
	        setpoint((PLINT) (xx2+i), (PLINT) (yy2+j));
	    }
	}
    }
    if (abs_dx >= abs_dy) {
	residual = -(abs_dx >> 1);
	if (width == 1) {
            for (i = 0; i <= abs_dx; i++, xx1 += incx) {
                setpoint((PLINT) (xx1), (PLINT) (yy1));
                if ((residual += abs_dy) >= 0) {
                    residual -= abs_dx;
                    yy1 += incy;
                }
            }
	}
	else {
	    for (i = 0; i <= abs_dx; i++, xx1 += incx) {
	       for (j = 0; j < width; j++) {
	           setpoint((PLINT) (xx1), (PLINT) (yy1+j));
	           setpoint((PLINT) (xx1+width-1), (PLINT) (yy1+j));
	       }
	       if ((residual += abs_dy) >= 0) {
		   residual -= abs_dx;
		   yy1 += incy;
	       }
	    }
	}
    }
Пример #7
0
/*
** Test crossings side.
*/
static void test_lw_segment_intersects(void)
{

#define setpoint(p, x1, y1) {(p).x = (x1); (p).y = (y1);}

	POINT2D p1, p2, q1, q2;

	/* P: Vertical line at x=0 */
	setpoint(p1, 0.0, 0.0);
	p1.x = 0.0;
	p1.y = 0.0;
	p2.x = 0.0;
	p2.y = 1.0;

	/* Q: Horizontal line crossing left to right */
	q1.x = -0.5;
	q1.y = 0.5;
	q2.x = 0.5;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_CROSS_RIGHT );

	/* Q: Horizontal line crossing right to left */
	q1.x = 0.5;
	q1.y = 0.5;
	q2.x = -0.5;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_CROSS_LEFT );

	/* Q: Horizontal line not crossing right to left */
	q1.x = 0.5;
	q1.y = 1.5;
	q2.x = -0.5;
	q2.y = 1.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_NO_INTERSECTION );

	/* Q: Horizontal line crossing at second vertex right to left */
	q1.x = 0.5;
	q1.y = 1.0;
	q2.x = -0.5;
	q2.y = 1.0;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_NO_INTERSECTION );

	/* Q: Horizontal line crossing at first vertex right to left */
	q1.x = 0.5;
	q1.y = 0.0;
	q2.x = -0.5;
	q2.y = 0.0;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_CROSS_LEFT );

	/* Q: Diagonal line with large range crossing at first vertex right to left */
	q1.x = 0.5;
	q1.y = 10.0;
	q2.x = -0.5;
	q2.y = -10.0;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_CROSS_LEFT );

	/* Q: Diagonal line with large range crossing at second vertex right to left */
	q1.x = 0.5;
	q1.y = 11.0;
	q2.x = -0.5;
	q2.y = -9.0;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_NO_INTERSECTION );

	/* Q: Horizontal touching from left at second vertex*/
	q1.x = -0.5;
	q1.y = 0.5;
	q2.x = 0.0;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_NO_INTERSECTION );

	/* Q: Horizontal touching from right at first vertex */
	q1.x = 0.0;
	q1.y = 0.5;
	q2.x = 0.5;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_CROSS_RIGHT );

	/* Q: Horizontal touching from left and far below on second vertex */
	q1.x = -0.5;
	q1.y = -10.5;
	q2.x = 0.0;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_NO_INTERSECTION );

	/* Q: Horizontal touching from right and far above on second vertex */
	q1.x = 0.5;
	q1.y = 10.5;
	q2.x = 0.0;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_NO_INTERSECTION );

	/* Q: Co-linear from top */
	q1.x = 0.0;
	q1.y = 10.0;
	q2.x = 0.0;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_COLINEAR );

	/* Q: Co-linear from bottom */
	q1.x = 0.0;
	q1.y = -10.0;
	q2.x = 0.0;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_COLINEAR );

	/* Q: Co-linear contained */
	q1.x = 0.0;
	q1.y = 0.4;
	q2.x = 0.0;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_COLINEAR );

	/* Q: Horizontal touching at end point from left */
	q1.x = -0.5;
	q1.y = 1.0;
	q2.x = 0.0;
	q2.y = 1.0;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_NO_INTERSECTION );

	/* Q: Horizontal touching at end point from right */
	q1.x = 0.0;
	q1.y = 1.0;
	q2.x = 0.0;
	q2.y = 0.5;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_COLINEAR );

	/* Q: Horizontal touching at start point from left */
	q1.x = 0.0;
	q1.y = 0.0;
	q2.x = -0.5;
	q2.y = 0.0;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_CROSS_LEFT );

	/* Q: Horizontal touching at start point from right */
	q1.x = 0.0;
	q1.y = 0.0;
	q2.x = 0.5;
	q2.y = 0.0;
	CU_ASSERT( lw_segment_intersects(&p1, &p2, &q1, &q2) == SEG_CROSS_RIGHT );

}