Vec2 ScallopedSector::sample(RNG &rng) { float angle = calcAngleForArea(area*rng.getFloatL(), rng); float d1 = distToCurve(angle, 0); float d2 = distToCurve(angle, 1); float d = sqrt(d1*d1 + (d2*d2 - d1*d1)*rng.getFloat()); return Vec2(P.x + cos(angle)*d, P.y + sin(angle)*d); }
static double totalMeanError(const vector<Vector2f> &dataPoints, const vector<Vector2f> &curve) { double distance = 0.0; for(int i = 1; i < dataPoints.size()-1; ++i) distance += distToCurve(dataPoints[i], curve); distance /= (dataPoints.size()-2); return distance; }
void ScallopedSector::subtractDisk(Vec2 &C, float r, std::vector<ScallopedSector> *regions) { std::vector<float> angles; Vec2 v(C.x - P.x, C.y-P.y); float d = sqrt(v.x*v.x + v.y*v.y); if (r<d) { float theta = atan2(v.y, v.x); float x = sqrt(d*d-r*r); float angle, alpha = asin(r/d); angle = canonizeAngle(theta+alpha); if (a1<angle && angle<a2) { if (distToCurve(angle,0)<x && x<distToCurve(angle,1)) angles.push_back(angle); } angle = canonizeAngle(theta-alpha); if (a1<angle && angle<a2) { if (distToCurve(angle,0)<x && x<distToCurve(angle,1)) angles.push_back(angle); } } for (int arcIndex=0; arcIndex<2; arcIndex++) { Vec2 &C2 = arcs[arcIndex].P; float R = arcs[arcIndex].r; Vec2 v(C.x - C2.x, C.y - C2.y); float d = sqrt(v.x*v.x + v.y*v.y); if (d>FLT_EPSILON) { float invD = 1.0f/d; float x = (d*d - r*r + R*R)*invD*.5f; float k = R*R - x*x; if (k>0) { float y = sqrt(k); float vx = v.x*invD; float vy = v.y*invD; float vx_x = vx*x, vy_x = vy*x; float vx_y = vx*y, vy_y = vy*y; float angle; angle = canonizeAngle(atan2(C2.y + vy_x + vx_y - P.y, C2.x + vx_x - vy_y - P.x)); if (a1<angle && angle<a2) angles.push_back(angle); angle = canonizeAngle(atan2(C2.y + vy_x - vx_y - P.y, C2.x + vx_x + vy_y - P.x)); if (a1<angle && angle<a2) angles.push_back(angle); } } } sort(angles.begin(), angles.end()); angles.insert(angles.begin(), a1); angles.push_back(a2); for (unsigned int i=1; i<angles.size(); i++) { float a1 = angles[i-1], a2 = angles[i]; float midA = (a1+a2)*.5f; float inner = distToCurve(midA,0); float outer = distToCurve(midA,1); float d1, d2; distToCircle(midA, C, r, &d1, &d2); // d1<=d2 if (d2<inner || d1>outer) { regions->push_back(ScallopedSector(P, a1, a2, arcs[0].P, arcs[0].r, arcs[0].sign, arcs[1].P, arcs[1].r, arcs[1].sign)); } else { if (inner<d1) { regions->push_back(ScallopedSector(P, a1, a2, arcs[0].P, arcs[0].r, arcs[0].sign, C, r, -1)); } if (d2<outer) { regions->push_back(ScallopedSector(P, a1, a2, C, r, 1, arcs[1].P, arcs[1].r, arcs[1].sign)); } } } }