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(); } }