Arc Arc::createArcBulge(const Coordinate &p1, const Coordinate &p2, const double bulge) { auto isCCW = bulge>0.; auto delta = atan(bulge) * 4.0; auto middle = p1.mid(p2); auto dist = p1.distanceTo(p2)/2.0; auto radius = std::abs(dist / std::sin(delta/2.0)); auto wu = std::abs(std::pow(radius, 2.0) - std::pow(dist, 2.0)); auto h = std::sqrt(wu); auto angle = p1.angleTo(p2); if (isCCW) { angle -= M_PI/2.0; } else { angle += M_PI/2.0; } if (std::abs(delta) < M_PI) { h*=-1.0; } auto center = geo::Coordinate(angle) * h + middle; return Arc(center, radius, center.angleTo(p1), center.angleTo(p2), isCCW); }