【计几】反演变换

反演变换

  • 反演变换适用于题目中存在多个圆/直线之间的相切关系的情况。利用反演变换的性质,在反演空间求解问题,可以大幅简化计算。

具体讲解:- 反演变换-OIwiki

模板来源:

题目集:


关于反演变换的补充:

1 . 要注意直线过反演点的特殊情况。

2 . 不过反演中心的直线反演之后内外侧会置换。那么直线和一个相切的圆的反演有两种情况:

  • 直线过反演中心:反演后直线还是过反演中心

  • 直线不过反演中心:如果原本反演中心和圆心在直线的同一侧,反演后两心位于异侧。反之,反演后两心位于同侧


板子:

struct circle{
    point o;
    double r;
};
point ptp(point a, point p, double r)          // 保证a和p不重合,否则会出现除以零的情况
{
    point v = a - p;
    double len = r * r / get_dis(p, a);
    return p + norm(v) * len;
}
circle ctc(circle c, point p, double r)        // 保证c不过p点
{
    circle res;
    double t = get_dis(p, c.o);
    double x = r * r / (t - c.r), y = r * r / (t + c.r);
    res.r = (x - y) / 2;

    double s = (x + y) / 2;
    res.o = p + norm(c.o - p) * s;
    return res;
}
void ctl(circle c, point & a, point & b, point p, double r) // 保证c过p点
{
    point v = c.o - p;
    double d = r * r / (2 * c.r);
    a = p + norm(v) * d;
    b = a + rotate(a, pi / 2);
}
circle ltc(point a, point b, point p, double r)            // 保证l不过点p
{
    double d = dis_to_line(a, b, p);
    d = r * r / d;
    circle res;
    res.r = d / 2;

    point v;
    if(area(a, b, p) > 0) v = rotate(b - a, -pi/2);
    else v = rotate(a - b, -pi/2);
    res.o = p + norm(v) * res.r;
    return res;
}

【计几】反演变换题集

上一篇:几行代码将方角照片变成圆角? 安排!


下一篇:Deeply-supervised Knowledge Synergy 深度监督知识协同