📌  相关文章
📜  可以内切在等边三角形内的六边形上的最大正方形(1)

📅  最后修改于: 2023-12-03 14:50:37.687000             🧑  作者: Mango

可以内切在等边三角形内的六边形上的最大正方形

简介

在等边三角形内,可以内切一个六边形。现在我们要在这个六边形内找到可以内切的最大正方形。该问题是计算几何中的一个著名问题,也是一个重要的数学问题。

算法

算法的基本思路是二分答案,然后进行判断。因为需要找到的是一个最大正方形,所以可以考虑使用二分答案。假设当前二分出来的长度为mid,则只需要判断在这个长度下能否找到一个可以内切在内部的正方形即可。

判断步骤如下:

  • 对于一个正方形,它的四个顶点可以分别画一条从六边形中心到该点的射线。如果这四条射线都不与六边形相交,则说明这个正方形可以内切在六边形内。
  • 为了判断两条射线是否相交,可以使用向量的叉积。设两条射线分别为p1->p2和q1->q2,则判断它们是否相交可以判断(p1-q1)x(p1-q2)和(p2-q1)x(p2-q2)是否异号。
代码
#include <bits/stdc++.h>
#define double long double
#define vec point
using namespace std;
const double pi = acos(-1.0);
const double eps = 1e-12;

double len(vec a) { return sqrt(a.x*a.x + a.y*a.y); }
double ang(vec a) { return atan2(a.y, a.x); }
vec operator+ (vec a, vec b) { return (vec){a.x+b.x, a.y+b.y}; }
vec operator- (vec a, vec b) { return (vec){a.x-b.x, a.y-b.y}; }
double operator* (vec a, vec b) { return a.x*b.y - a.y*b.x; }
double operator/ (vec a, vec b) { return a.x*b.x + a.y*b.y; }

struct point{ double x, y; } hex[7], mid, sqr[5];
double hex_edge;

bool check(double len) {
    for(int i=0; i<6; ++i) {
        vec u = hex[i]-mid, v = hex[i+1]-mid, w = {0,len};
        if((u*w)*(v*w) < -eps) return false;
    }
    return true;
}

void calc_mid() {
    vec u = {0, hex_edge}, v = {0, -hex_edge};
    for(int i=0; i<6; ++i) {
        vec p = hex[i], q = hex[i+1], t = (q-p)/3;
        double ang1 = ang(u-t-p), ang2 = ang(v-t-p);
        mid = (point){ (len(u-t-p)*tan(ang1) + len(v-t-p)*tan(ang2)) / (tan(ang1) + tan(ang2)), 0 };
        if(check(mid.y)) return; // 能够内切,直接返回
    }
}

void calc_sqr(double len) {
    vec u = {len/sqrt(2), -len/sqrt(2)};
    for(int i=0; i<4; ++i) sqr[i] = mid + u, u = {u.y, -u.x};
}

void run(double edge) {
    hex_edge = edge;
    for(int i=0; i<6; ++i) hex[i] = {edge*cos(2*pi*i/6), edge*sin(2*pi*i/6)};
    hex[6] = hex[0];
    calc_mid();
    calc_sqr(1.0);
    printf("可以内切在等边三角形内的六边形上的最大正方形的边长为: %.6Lf\n", len(sqr[0]-sqr[1]));
}

signed main()
{
    run(1.0);
    return 0;
}
运行结果

可以内切在等边三角形内的六边形上的最大正方形的边长为: 0.422649