FlatEllipse::FlatEllipse(const FlatPoint &_f1, const FlatPoint &_f2, const FlatPoint &_ap) :f1(_f1),f2(_f2),ap(_ap) { const FlatLine f12(f1, f2); p = f12.ave(); theta = f12.angle(); const fixed csq = f12.dsq(); a = (f1.d(ap) + f2.d(ap)); b = half(sqrt(a * a - csq)); a = half(a); // a.sin(t) = ap.x // b.cos(t) = ap.y FlatPoint op = ap; op.sub(p); op.rotate(-theta); theta_initial = Angle::radians(atan2(op.y * a, op.x * b)).as_delta(); }
FlatEllipse::FlatEllipse(const FlatPoint &_f1, const FlatPoint &_f2, const FlatPoint &_ap) :f1(_f1),f2(_f2),ap(_ap) { const FlatLine f12(f1, f2); p = f12.ave(); theta = f12.angle(); const fixed csq = f12.dsq(); a = (f1.Distance(ap) + f2.Distance(ap)); b = half(sqrt(sqr(a) - csq)); a = half(a); // a.sin(t) = ap.x // b.cos(t) = ap.y FlatPoint op = ap; op.Subtract(p); op.Rotate(-theta); theta_initial = Angle::Radians(atan2(op.y * a, op.x * b)).AsDelta(); }
bool FlatEllipse::intersect(const FlatLine &line, FlatPoint &i1, FlatPoint &i2) const { const fixed er = ab(); const fixed ier = ba(); FlatLine s_line = line; s_line.sub(p); s_line.rotate(theta.Reciprocal()); s_line.mul_y(er); if (s_line.intersect_czero(a, i1, i2)) { i1.mul_y(ier); i1.rotate(theta); i1.add(p); i2.mul_y(ier); i2.rotate(theta); i2.add(p); return true; } return false; }
FlatEllipse::FlatEllipse(const FlatPoint &_f1, const FlatPoint &_f2, const FlatPoint &_ap) :f1(_f1),f2(_f2),ap(_ap) { const FlatLine f12(f1, f2); p = f12.GetMiddle(); theta = f12.GetAngle(); const auto csq = f12.GetSquaredDistance(); a = (f1.Distance(ap) + f2.Distance(ap)); assert(Square(a) >= csq); b = sqrt(Square(a) - csq) / 2; a /= 2; // a.sin(t) = ap.x // b.cos(t) = ap.y FlatPoint op = ap; op -= p; op.Rotate(-theta); theta_initial = Angle::FromXY(op.x * b, op.y * a).AsDelta(); }
bool FlatEllipse::Intersect(const FlatLine &line, FlatPoint &i1, FlatPoint &i2) const { const double er = ab(); const double ier = ba(); FlatLine s_line = line - p; s_line.Rotate(theta.Reciprocal()); s_line.MultiplyY(er); if (s_line.IntersectOriginCircle(a, i1, i2)) { i1.MultiplyY(ier); i1.Rotate(theta); i1 += p; i2.MultiplyY(ier); i2.Rotate(theta); i2 += p; return true; } return false; }