예제 #1
0
int isLegalMoveQueen(int kingCellId, int queenCellId, int newQueenCellId)
{
    if(kingCellId == newQueenCellId)
        return 0;
    if(newQueenCellId == queenCellId)
        return 0;   /* The queen is not moved at all */

    if(onSameCol(newQueenCellId, queenCellId))
    {
        /* The two positions are in the same column */
        if(onSameCol(kingCellId, queenCellId))
            return !isBetween(kingCellId, queenCellId, newQueenCellId);

        return 1;
    }

    if(onSameRow(newQueenCellId, queenCellId))
    {
        /* The two positions are in the same row */
        if(onSameRow(kingCellId, queenCellId))
            return !isBetween(kingCellId, queenCellId, newQueenCellId);

        return 1;
    }

    return 0;
}
예제 #2
0
// On Windows, when tags are applied, 38% of CPU time is used for
// seven oovBuilder source modules open.  This is true even though the
// applyTags function is not normally running while idle. When only half
// the tags for each file is applied, then it drops to 25% usage.
bool Highlighter::applyTags(GtkTextBuffer *textBuffer,
        int topOffset, int botOffset)
    {
    DUMP_THREAD("applyTags");
    mHighlightTags.initTags(textBuffer);
    const TokenRange &tokens = mHighlightTokens;

    if(mTokenState != TS_HighlightRequest)
        {
        if(mTokenState == TS_GotTokens)
            {
            mTokenState = TS_AppliedTokens;
            }
        GtkTextIter start;
        GtkTextIter end;
        gtk_text_buffer_get_bounds(textBuffer, &start, &end);
        gtk_text_buffer_remove_all_tags(textBuffer, &start, &end);
        for(size_t i=0; i<tokens.size(); i++)
            {
            if(isBetween(tokens[i].mStartOffset, topOffset, botOffset) ||
                isBetween(tokens[i].mEndOffset, topOffset, botOffset) ||
                isBetween(topOffset, tokens[i].mStartOffset, tokens[i].mEndOffset))
                {
                gtk_text_buffer_get_iter_at_offset(textBuffer, &start,
                    static_cast<gint>(tokens[i].mStartOffset));
                gtk_text_buffer_get_iter_at_offset(textBuffer, &end,
                    static_cast<gint>(tokens[i].mEndOffset));
                gtk_text_buffer_apply_tag(textBuffer,
                    mHighlightTags.getTag(tokens[i].mTokenKind), &start, &end);
                }
            }
        }
    DUMP_THREAD("applyTags-end");
    return(mTokenState == TS_AppliedTokens);
    }
예제 #3
0
 //returns true if (x,y) is inside sprite fiure
 bool contains(float x, float y, const sf::Sprite& sprite)
 {
     
     float minX = sprite.GetPosition().x;
     float minY = sprite.GetPosition().y;
     
     float maxX = sprite.GetPosition().x + sprite.GetSize().x;
     float maxY = sprite.GetPosition().y + sprite.GetSize().y;
     
     //return if x and y falls in between sprite's range
     return isBetween(x,minX, maxX) && isBetween(y,minY, maxY);
 }
예제 #4
0
bool isPointOnLine(double x, double y, double x1, double y1, double x2, double y2, double tolerance) {
  if ( isBetween(x, x1, x2, tolerance) && isBetween(y, y1, y2, tolerance) ){
    if ( (x2 - x1) == 0.0 )
	return true; 
      
      double slope = (y2 - y1) / (x2 - x1);
      double yintercept = y1 - slope * x1;
      
      return ( fabs( y - ( slope * x + yintercept )) <= tolerance );
    }
    return false; 
  }
예제 #5
0
bool CollisionDetection::checkLineIntersect(Point _p1, Point _p2, Point _p3, Point _p4)
{
	if ((_p1.x - _p2.x)*(_p3.y - _p4.y) - (_p1.y - _p2.y)*(_p3.x - _p4.x) != 0)
	{
		if (isBetween(_p1.x, _p2.x, getLineIntersect(_p1, _p2, _p3, _p4).x)) {
			if (isBetween(_p3.x, _p4.x, getLineIntersect(_p1, _p2, _p3, _p4).x)) {
				if (isBetween(_p1.y, _p2.y, getLineIntersect(_p1, _p2, _p3, _p4).y)) {
					if (isBetween(_p3.y, _p4.y, getLineIntersect(_p1, _p2, _p3, _p4).y)) {
						return true;
					}
				}
			}
		}
	}
	return false;
}
예제 #6
0
/*private*/
void
ConvexHull::cleanRing(const Coordinate::ConstVect &original,
		Coordinate::ConstVect &cleaned)
{
	size_t npts=original.size();

	const Coordinate *last = original[npts-1];

	//util::Assert::equals(*(original[0]), *last);
	assert(last);
	assert(original[0]->equals2D(*last));

	const Coordinate *prev = NULL;
	for (size_t i=0; i<npts-1; ++i)
	{
		const Coordinate *curr = original[i];
		const Coordinate *next = original[i+1];

		// skip consecutive equal coordinates
		if (curr->equals2D(*next)) continue;

		if ( prev != NULL &&  isBetween(*prev, *curr, *next) )
		{
			continue;
		}

		cleaned.push_back(curr);
		prev=curr;
	}

	cleaned.push_back(last);

}
예제 #7
0
 /**
  * @brief      Reads the game settings from file and creates a GameSettings
  *             structure
  *
  * @param      *buffer - file stream buffer
  * @param      *settingsFile - file pointer
  *
  * @return     void
  */
 GameSettings readGameSettings(char *buffer, FILE *settingsFile) {
     int numDecks=0, numPlayers=0;
     if(fgets(buffer, MAX_BUFFER_SIZE, settingsFile) == NULL) {
         fireFileIsEmptyError("Settings file");
     }
     if(sscanf(buffer, "%d-%d", &numDecks, &numPlayers) == -1) {
         fireFormatError("[NumDecks]-[NumPlayers]");
     }

     if(!isBetween(numDecks, MIN_DECKS, MAX_DECKS)) fireOutOfRangeError("number of decks", MIN_DECKS, MAX_DECKS);
     if(!isBetween(numPlayers, MIN_PLAYERS, TABLE_SLOTS)) fireOutOfRangeError("number of players",MIN_PLAYERS,TABLE_SLOTS);

     GameSettings gameStg = {numDecks, numPlayers};

     return gameStg;
 }
예제 #8
0
void ptFilter_SpotTuning::updateSpotDetailsGui(int ASpotIdx, QWidget *AGuiWidget /*=nullptr*/) {
  ptTuningSpot *hSpot = nullptr;
  if (isBetween(0, ASpotIdx, FSpotList.count()-1)) {
    hSpot = static_cast<ptTuningSpot*>(FSpotList.at(ASpotIdx));
    FGui->SpotDetailsGroup->setEnabled(true);
  } else {
    hSpot = FNullSpot.get();
    FGui->SpotDetailsGroup->setEnabled(false);
  }

  if (AGuiWidget == nullptr)
    AGuiWidget = FGuiContainer;

  FGui->CurveWin->updateView(hSpot->curve());

  for (const ptCfgItem &hCfgItem: FConfig.items()) {
    if (hCfgItem.Type < ptCfgItem::CFirstCustomType) {
      ptWidget *hWidget = this->findPtWidget(hCfgItem.Id, AGuiWidget);
      hWidget->blockSignals(true);
      hWidget->setValue(hSpot->value(hCfgItem.Id));
      hWidget->blockSignals(false);
    }
  }

  FGui->MaxRadius->setEnabled(hSpot->value("HasMaxRadius").toBool());
}
예제 #9
0
// Computes offset to track middle for trajectory.
float Pit::getPitOffset(float offset, float fromstart)
{
	if (mypit != NULL) {
		if (getInPit() || (getPitstop() && isBetween(fromstart))) {
			fromstart = toSplineCoord(fromstart);
			return spline->evaluate(fromstart);
		}
	}
	return offset;
}
예제 #10
0
파일: pit.cpp 프로젝트: COHRINT/cuTORCS
/* Sets the pitstop flag if we are not in the pit range */
void Pit::setPitstop(bool pitstop)
{
	if (mypit == NULL) return;
	float fromstart = car->_distFromStartLine;

	if (!isBetween(fromstart)) {
		this->pitstop = pitstop;
	} else if (!pitstop) {
		this->pitstop = pitstop;
	}
}
balazs::Mod1NumberIntExchange balazs::TransverseCurve::distanceOnCurve(const Mod1NumberIntExchange &x,
        const Mod1NumberIntExchange &y) const
{
    assert(m_disjointIntervals.strictlyContains(x) && m_disjointIntervals.strictlyContains(y));
    std::size_t index;
    std::size_t nextIndex;
    for(index = 0; index < m_intervalsInOrder.size(); index += 2) {
        nextIndex = (index + 1) % m_intervalsInOrder.size();
        if(isBetween(m_intervalsInOrder[index], m_intervalsInOrder[nextIndex], x)) break;
    }
    if(isBetween(x, m_intervalsInOrder[nextIndex], y)) {
        return y-x;
    }

    Mod1NumberIntExchange retval = m_intervalsInOrder[nextIndex] - x;
    index = (index + 2) % m_intervalsInOrder.size();
    nextIndex = (index + 1) % m_intervalsInOrder.size();
    while(!isBetween(m_intervalsInOrder[index], m_intervalsInOrder[nextIndex], y)) {
        retval += m_intervalsInOrder[nextIndex] - m_intervalsInOrder[index];
        index = (index + 2) % m_intervalsInOrder.size();
        nextIndex = (index + 1) % m_intervalsInOrder.size();
    }
    return retval + (y - m_intervalsInOrder[index]);
}
예제 #12
0
 /**
  * @brief      Reads the player settings from file and creates a PlayerSettings
  *             structure
  *
  * @param      *buffer - file stream buffer
  * @param      *settingsFile - file pointer
  * @param      numPlayers - number of players
  *
  * @return     void
  */
PlayerSettings *readPlayerSettings(char *buffer, FILE *settingsFile, int numPlayers) {

  char playerTypeChar[MAX_PLAYER_TYPE_SIZE+1];
  PlayerType  playerType;
  char name[MAX_NAME_SIZE+1];
  int seedMoney = 0;
  int seedBet = 0;

  PlayerSettings *playerStg =(PlayerSettings *) malloc(numPlayers*sizeof(PlayerSettings));

  int i = 0;
  while (fgets(buffer, MAX_BUFFER_SIZE, settingsFile)) {
    if(sscanf(buffer,"%[^-]-%[^-]-%d-%d", playerTypeChar, name, &seedMoney, &seedBet) == -1) {
      fireFormatError("[PlayerType]-[PlayerName]-[SeedMoney]-[SeedBetValue]");
    }

    if(!isBetween(seedMoney, 10, 500)) fireOutOfRangeError("seed money", 10, 500);
    if(!isBetween(seedBet, 2, 0.25*seedMoney)) fireOutOfRangeError("seed money", 2, 0.25*seedMoney);


    if(strcmp(playerTypeChar, "HU") == 0) playerType = HUMAN;
    else if(strcmp(playerTypeChar, "EA") == 0) playerType = CPU;
    else {
      fireUnknownValueError("HU or EA");
    }

    playerStg[i].playerType = playerType;
    playerStg[i].seedMoney = seedMoney;
    playerStg[i].seedBet = seedBet;
    strcpy(playerStg[i].name, name);

    i++;
  }

  return playerStg;
}
예제 #13
0
// Update pit data and strategy.
void Pit::update()
{
	if (mypit != NULL) {
		if (isBetween(car->_distFromStartLine)) {
			if (getPitstop()) {
				setInPit(true);
			}
		} else {
			setInPit(false);
		}

		if (getPitstop()) {
			car->_raceCmd = RM_CMD_PIT_ASKED;
		}
	}
}
예제 #14
0
파일: pit.cpp 프로젝트: COHRINT/cuTORCS
/* update pit data and strategy */
void Pit::update()
{
	if (mypit != NULL) {
		if (isBetween(car->_distFromStartLine)) {
			if (getPitstop()) {
				setInPit(true);
			}
		} else {
			setInPit(false);
		}

		/* check for damage */
		if (car->_dammage > PIT_DAMMAGE) {
			setPitstop(true);
		}

		/* fuel update */
		int id = car->_trkPos.seg->id;
		if (id >= 0 && id < 5 && !fuelchecked) {
			if (car->race.laps > 0) {
				fuelperlap = MAX(fuelperlap, (lastfuel+lastpitfuel-car->priv.fuel));
			}
			lastfuel = car->priv.fuel;
			lastpitfuel = 0.0;
			fuelchecked = true;
		} else if (id > 5) {
			fuelchecked = false;
		}

		int laps = car->_remainingLaps-car->_lapsBehindLeader;
		if (!getPitstop() && laps > 0) {
			if (car->_fuel < 1.5*fuelperlap &&
				car->_fuel < laps*fuelperlap) {
				setPitstop(true);
			}
		}

		if (getPitstop()) car->_raceCmd = RM_CMD_PIT_ASKED;
	}
}
예제 #15
0
inline QList<Coord> getPointList( const Coord& origin, const Coord& target )
{
	// Create a list of coordinates we are going to "touch" when looking
	// from point a to point b
	QList<Coord> pointList;

	int xDiff = target.x - origin.x;
	int yDiff = target.y - origin.y;
	int zDiff = target.z - origin.z;

	// Calculate the length of the X,Y diagonal
	double xyDiagonal = sqrt( ( double ) ( xDiff* xDiff + yDiff* yDiff ) );

	// Calculate the length of the second diagonal
	double lineLength;
	if ( zDiff != 0 )
	{
		lineLength = sqrt( xyDiagonal * xyDiagonal + ( double ) ( zDiff * zDiff ) );
	}
	else
	{
		lineLength = xyDiagonal;
	}

	// Calculate the stepsize for each coordinate
	double xStep = xDiff / lineLength;
	double yStep = yDiff / lineLength;
	double zStep = zDiff / lineLength;

	// Initialize loop variables
	double currentY = origin.y;
	double currentZ = origin.z;
	double currentX = origin.x;

	Coord pos = origin;

	while ( isBetween( currentX, target.x, origin.x ) && isBetween( currentY, target.y, origin.y ) && isBetween( currentZ, target.z, origin.z ) )
	{
		pos.x = roundInt( currentX );
		pos.y = roundInt( currentY );
		pos.z = roundInt( currentZ );

		if ( pointList.count() == 0 || pointList.last() != pos )
		{
			pointList.append( pos );
		}

		// Jump to the next set of coordinates.
		currentX += xStep;
		currentY += yStep;
		currentZ += zStep;
	}

	// Add the target to the end of the pointlist if it's not already
	// there
	if ( pointList.count() != 0 && pointList.last() != target )
	{
		pointList.append( target );
	}

	return pointList;
}
예제 #16
0
double
SpeedSetPoint::currentCmdSpeed( bool &setPointAlreadyReached )
{
    // dt_ can actually be negative, e.g. if ntp steps the clock backwards...
    if ( dt_ <= 0.0 )
    {
        cout<<"TRACE(speedsetpoint.cpp): warning: found negative dt_: " << dt_ << ".  Setting dt_ to 0.01." << endl;
        dt_ = 0.01;
    }

    double cmdSpeedPrior = currentCmdSpeed_;

    const double diff = setPoint_ - currentCmdSpeed_;
    const bool speedIncreasing = (diff > 0);

    // cout<<"TRACE(speedsetpoint.cpp): setPoint_: " << setPoint_ << ", currentCmdSpeed_: " << currentCmdSpeed_ << ", diff: " << diff << endl;

    if ( fabs(diff) < 1e-9 )
    {
        setPointAlreadyReached = true;
        return currentCmdSpeed_;
    }

    double maxDeltaSpeed; // This is a positive quantity.
    if ( speedIncreasing )
    {
        maxDeltaSpeed = maxForwardAcceleration_ * dt_;
    }
    else
    {
        maxDeltaSpeed = maxReverseAcceleration_ * dt_;
    }

    bool willReachSetPoint = ( fabs(diff) < maxDeltaSpeed );
    if ( willReachSetPoint )
    {
        currentCmdSpeed_ = setPoint_;
    }
    else
    {
        if ( speedIncreasing )
        {
            currentCmdSpeed_ += maxDeltaSpeed;
            assert( currentCmdSpeed_ <= setPoint_ );
        }
        else
        {
            currentCmdSpeed_ -= maxDeltaSpeed;
            assert( currentCmdSpeed_ >= setPoint_ );
        }
    }

    // Hard-coded safety check...
    if ( currentCmdSpeed_ > 4.0 )
    {
        stringstream ss;
        ss << "Attempted to command infeasibly-large speed: " << currentCmdSpeed_ << "m/s";
        throw gbxutilacfr::Exception( ERROR_INFO, ss.str() );
    }
    // Another safety check...
    assert( isBetween( currentCmdSpeed_, cmdSpeedPrior, setPoint_ ) );

    return currentCmdSpeed_;
}
예제 #17
0
/*
	Calculates the coordinates of the collision point
*/
void Convex::convexCollision(Convex* other, sf::RenderWindow* window)
{
	sf::Vector2f collisionNormal;
	float collisionX, collisionY;
	float x1, x2, x3, x4, y1, y2, y3, y4;
	

	if (hasCollided(other))
	{
		for (int i = 0; i < getPointCount(); i++)
		{
			//Retrieves the coordinates of the point i
			x1 = this->getPoint(i).x;
			y1 = this->getPoint(i).y;

			//If the index 'i' equals the amount of points
			//the other end of the line should be the starting point
			if (i == getPointCount() - 1)
			{
				x2 = this->getPoint(0).x;
				y2 = this->getPoint(0).y;
			}
			else
			{
				x2 = this->getPoint(i + 1).x;
				y2 = this->getPoint(i + 1).y;
			}


			for (int j = 0; j < other->getPointCount(); j++)
			{
				x3 = other->getPoint(j).x;
				y3 = other->getPoint(j).y;

				//If the index 'j' equals the amount of points
				//the other end of the line should be the starting point
				if (i == getPointCount() - 1)
				{
					x4 = other->getPoint(0).x;
					y4 = other->getPoint(0).y;
				}
				else
				{
					x4 = other->getPoint(i + 1).x;
					y4 = other->getPoint(i + 1).y;
				}

				collisionX = vectorProduct(vectorProduct(x1, y1, x2, y2),
							 vectorProduct(x1, 1, x2, 1),
							 vectorProduct(x3, y3, x4, y4),
							 vectorProduct(x3, 1, x4, 1))
							 /
							 vectorProduct(vectorProduct(x1, 1, x2, 1),
							 vectorProduct(y1, 1, y2, 1),
							 vectorProduct(x3, 1, x4, 1),
							 vectorProduct(y3, 1, y4, 1));

				collisionY = vectorProduct(vectorProduct(x1, y1, x2, y2),
							 vectorProduct(y1, 1, y2, 1),
							 vectorProduct(x3, y3, x4, y4),
							 vectorProduct(y3, 1, y4, 1))
							 /
							 vectorProduct(vectorProduct(x1, 1, x2, 1),
							 vectorProduct(y1, 1, y2, 1),
							 vectorProduct(x3, 1, x4, 1),
							 vectorProduct(y3, 1, y4, 1));
				
				//Checking that the collision point is actually between the corners
				//of the convexes
				if (isBetween(collisionX, x1, x2) && isBetween(collisionX, x3, x4) &&
					isBetween(collisionY, y1, y2) && isBetween(collisionY, y3, y4))
				{
					//If the collision point is between these points use them to calculate the
					//collisionNormal's components
					if (isBetween(collisionX, x1, x2) && isBetween(collisionY, y1, y2))
					{
						float x = x2 - x1;
						float y = y2 - y1;
						
						float length = sqrt(pow(x, 2) + pow(y, 2));
						float unitX = x / length;
						float unitY = y / length;

						collisionNormal.x = -unitY;
						collisionNormal.y = unitX;

						float impulse = getImpulse(&sf::Vector2f(collisionX, collisionY), &collisionNormal, other, this);
						applyChanges(&collisionNormal, impulse, &sf::Vector2f(collisionX, collisionY), other, this);
					}
					else
					{
						float x = x4 - x3;
						float y = y4 - y3;

						float length = sqrt(pow(x, 2) + pow(y, 2));
						float unitX = x / length;
						float unitY = y / length;

						collisionNormal.x = -unitY;
						collisionNormal.y = unitX;

						float impulse = getImpulse(&sf::Vector2f(collisionX, collisionY), &collisionNormal, this, other);
						applyChanges(&collisionNormal, impulse, &sf::Vector2f(collisionX, collisionY), this, other);
					}
					
					sf::CircleShape circle(5);
					circle.setFillColor(sf::Color::Red);
					circle.setPosition(collisionX, collisionY);
					window->draw(circle);
				}
			}
		}
	}
}
예제 #18
0
 /** 
  * calculate the intersection of the segment and a given line
  * 
  * @param line the given line
  * @param intersection retrun the intersection
  * 
  * @return if the segment and line have intersection
  */
 bool calIntersection(const TLine2<DATATYPE>& line,
                      TVector<DATATYPE,2>& intersection)const
     {
         intersection = TLine2<DATATYPE>::calIntersection(line);
         return isBetween(intersection);
     }
예제 #19
0
파일: point.cpp 프로젝트: LeiDai/agros2d
QList<Point> intersection(const Point &p1s, const Point &p1e, const Point &center1, double radius1, double angle1,
                          const Point &p2s, const Point &p2e, const Point &center2, double radius2, double angle2)
{
    QList<Point> out;

    double dx = p1e.x - p1s.x;      // component of direction vector of the line
    double dy = p1e.y - p1s.y;      // component of direction vector of the line
    double a = dx * dx + dy * dy;   // square of the length of direction vector
    double tol = a / 1e4;

    // Crossing of two arcs
    if ((angle1 > 0.0) && (angle2 > 0.0))
    {
        if (((p1s == p2e) && (p1e == p2s)) || ((p1e == p2e) && (p1s == p2s)))
        {
            // Crossing of arcs is not possible
        }
        else
        {
            // Calculate distance between centres of circle
            double distance = (center1 - center2).magnitude();
            double dx = center2.x - center1.x;
            double dy = center2.y - center1.y;

            if ((distance < (radius1 + radius2)))
            {
                // Determine the distance from point 0 to point 2.
                double a = ((radius1*radius1) - (radius2*radius2) + (distance*distance)) / (2.0 * distance);

                // Determine the coordinates of point 2.
                Point middle(center1.x + (dx * a/distance),
                             center1.y + (dy * a/distance));

                // Determine the distance from point 2 to either of the
                // intersection points.
                double h = sqrt((radius1 * radius1) - (a*a));

                // Now determine the offsets of the intersection points from
                // point 2.
                double rx = -dy * (h/distance);
                double ry =  dx * (h/distance);

                // Determine the absolute intersection points.
                Point p1(middle.x + rx, middle.y + ry);
                Point p2(middle.x - rx, middle.y - ry);

                // Test if intersection 1 lies on arc
                if ((isBetween((p1e - center1), (p1s - center1), (p1 - center1)) && isBetween((p2e - center2), (p2s - center2), (p1 - center2))))
                {
                    if (((p1 - p1s).magnitudeSquared() > tol) &&
                            ((p1 - p1e).magnitudeSquared() > tol) &&
                            ((p1 - p2e).magnitudeSquared() > tol) &&
                            ((p1 - p2s).magnitudeSquared() > tol))
                        out.append(p1);
                }

                // Test if intersection 1 lies on arc
                if (isBetween((p1e - center1), (p1s - center1), (p2 - center1)) && isBetween((p2e - center2), (p2s - center2), (p2 - center2)))
                {
                    if (((p2 - p1s).magnitudeSquared() > tol) &&
                            ((p2 - p1e).magnitudeSquared() > tol) &&
                            ((p2 - p2e).magnitudeSquared() > tol) &&
                            ((p2 - p2s).magnitudeSquared() > tol))
                        out.append(p2);
                }
            }
        }
    }
    else if (angle2 > 0.0)
    {
        // crossing of arc and line
        double b = 2 * (dx * (p1s.x - center2.x) + dy * (p1s.y - center2.y));
        double c = p1s.x * p1s.x + p1s.y * p1s.y + center2.x * center2.x + center2.y * center2.y - 2 * (center2.x * p1s.x + center2.y * p1s.y)-(radius2 * radius2);

        double bb4ac = sqrt(b * b - 4 * a * c);

        double mu1 = (-b + bb4ac) / (2*a);
        double mu2 = (-b - bb4ac) / (2*a);

        double i1x = p1s.x + mu1*(dx);
        double i1y = p1s.y + mu1*(dy);

        double i2x = p1s.x + mu2*(dx);
        double i2y = p1s.y + mu2*(dy);


        Point p1(i1x, i1y);     // possible intersection point
        Point p2(i2x, i2y);     // possible intersection point

        double t1;
        double t2;

        if (std::abs(dx - dy) > tol)
        {
            t1 = (p1.x - p1s.x - p1.y + p1s.y) / (dx - dy); // tangent
            t2 = (p2.x - p1s.x - p2.y + p1s.y) / (dx - dy); // tangent
        }
        else
        {
            t1 = (p1.x - p1s.x) / dx; // tangent
            t2 = (p2.x - p1s.x) / dx; // tangent
        }

        if ((t1 >= 0) && (t1 <= 1))
        {
            // 1 solution: One Point in the circle
            if (isBetween((p2e - center2), (p2s - center2), (p1 - center2)) && ((p1 - p2s).magnitudeSquared() > tol) && ((p1 - p2e).magnitudeSquared() > tol))
                out.append(p1);
        }

        if ((t2 >= 0) && (t2 <= 1))
        {
            // 1 solution: One Point in the circle
            if (isBetween((p2e - center2), (p2s - center2), (p2 - center2)) && ((p2 -  p2s).magnitudeSquared() > tol) && ((p2 - p2e).magnitudeSquared() > tol))
                out.append(p2);
        }
    }
    else
    {
        // straight line
        if ((p2e != p1s) && (p1e != p2s) && (p1e != p2e) && (p1s != p2s))
        {
            double denom = (p2e.y-p2s.y)*(p1e.x-p1s.x) - (p2e.x-p2s.x)*(p1e.y-p1s.y);

            if (abs(denom) > EPS_ZERO)
            {
                double nume_a = ((p2e.x-p2s.x)*(p1s.y-p2s.y) - (p2e.y-p2s.y)*(p1s.x-p2s.x));
                double nume_b = ((p1e.x-p1s.x)*(p1s.y-p2s.y) - (p1e.y-p1s.y)*(p1s.x-p2s.x));

                double ua = nume_a / denom;
                double ub = nume_b / denom;

                if ((ua >= 0.0) && (ua <= 1.0) && (ub >= 0.0) && (ub <= 1.0))
                {
                    double xi = p1s.x + ua*(p1e.x - p1s.x);
                    double yi = p1s.y + ua*(p1e.y - p1s.y);

                    out.append(Point(xi, yi));
                }
            }
        }
    }
    return out;
}