Example #1
0
unsigned short int Cline::intersectionsWithCircle(Cpoint c, double r, vector<Cpoint> &intersections)
{
    intersections.clear();

    // move circle to (0,0)
    //Cpoint p1 = aa - c; cout << "DEBUG: p1 is " << p1 << endl;
    //Cpoint p2 = bb - c; cout << "DEBUG: p2 is " << p2 << endl;
    Cpoint p1(aa.get_xx() - c.get_xx(), aa.get_yy() - c.get_yy()); //cout << "DEBUG: p1 is " << p1 << endl;
    Cpoint p2(bb.get_xx() - c.get_xx(), bb.get_yy() - c.get_yy()); //cout << "DEBUG: p1 is " << p1 << endl;

    // discriminant
    double dx = p2.get_xx() - p1.get_xx();
    double dy = p2.get_yy() - p1.get_yy();
    double dr_sq = dx*dx + dy*dy;
    double D = p1.get_xx() * p2.get_yy() - p2.get_xx() * p1.get_yy();
    double disc = r*r * dr_sq - D*D;

    if(disc < 0)
        return 0;
    else if(disc == 0)
    {
        double x = D * dy / dr_sq;
        double y = -D * dx / dr_sq;

        // check if point belongs to segment
        Cpoint i = Cpoint(x + c.get_xx(), y + c.get_yy());
        if( i.d2point2(&aa) <= aa.d2point2(&bb) && i.d2point2(&bb) <= aa.d2point2(&bb))
            intersections.push_back( i );
        return intersections.size();
    }
    else
    {
        int sign_dy = (dy >= 0) ? 1 : -1;
        double x1 = ( D * dy + sign_dy * dx * sqrt(disc) ) / dr_sq;
        double x2 = ( D * dy - sign_dy * dx * sqrt(disc) ) / dr_sq;
        double abs_dy = ( dy >= 0 ) ? dy : -dy;
        double y1 = ( -D * dx + abs_dy * sqrt(disc) ) / dr_sq;
        double y2 = ( -D * dx - abs_dy * sqrt(disc) ) / dr_sq;
        Cpoint i1 = Cpoint(x1 + c.get_xx(), y1 + c.get_yy());
        Cpoint i2 = Cpoint(x2 + c.get_xx(), y2 + c.get_yy());
        if( i1.d2point2(&aa) <= aa.d2point2(&bb) && i1.d2point2(&bb) <= aa.d2point2(&bb))
            intersections.push_back( i1 );
        if( i2.d2point2(&aa) <= aa.d2point2(&bb) && i2.d2point2(&bb) <= aa.d2point2(&bb))
            intersections.push_back( i2 );
        return intersections.size();
    }
}