知识点 - 多边形的重心、核、三角形的心

本文深入解析了几何学中的关键概念,包括多边形的重心、核、三角形的心以及费马点等,提供了详细的数学公式和算法实现,帮助读者理解和应用这些几何原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

知识点 - 多边形的重心、核、三角形的心

解决问题类型:

多边形的重心。

三角形的内、外、垂心。

三角形的费马点(到三点和距离最小)

复杂度与代码:

O(n)n为点数

多边形重心

即过这点的直线平分该多边形

#include <stdio.h>
#include <math.h>
int x[1000003], y[1000003];
double A, tx, ty, tmp;
int main (void)
{
    int cases, n, i;
    scanf ("%d", &cases);
    while (cases --)
    {
        scanf ("%d", &n);
        A = 0.0;
        x[0] = y[0] = 0;
        for (i = 1; i <= n; i ++)
        {
            scanf ("%d %d", &x[i], &y[i]);
            A += (x[i-1]*y[i] - x[i]*y[i-1]);
        }
        A += x[n]*y[1] - x[1]*y[n];
        A = A / 2.0;
        tx = ty = 0.0;
        for (i = 1; i < n; i ++)
        {
            tmp = x[i]*y[i+1] - x[i+1]*y[i];
            tx += (x[i]+x[i+1]) * tmp;
            ty += (y[i]+y[i+1]) * tmp;
        }
        tmp = x[n]*y[1] - x[1]*y[n];
        tx += (x[n]+x[1])*tmp;
        ty += (y[n]+y[1])*tmp;
        printf ("%.2lf %.2lf\n", tx/(6.0*A), ty/(6.0*A));
    }
    return 0;
}

多边形是否有核

星形多边形是什么呢?其实就是在多边形内部存在一个点A,这个点与多边形内任意一点的连线都在多边形内部,就叫做星形多边形,这一个点A就叫做多边形的内核。

多边形的核可以这样理解:这个核为原多边形内部的一个多边形,站在这个叫核的多边形中,我们能看到原多边形的任何一个位置。

解释与例题

#include <stdio.h>
#include <string.h>
const int INF = (1<<30);
struct Point
{
    int x, y;
}pt[150];
typedef struct Point Point;
bool turn_right[150];
int det(Point s1, Point t1, Point s2, Point t2)
{
    int d1x = t1.x-s1.x;
    int d1y = t1.y-s1.y;

    int d2x = t2.x-s2.x;
    int d2y = t2.y-s2.y;

    return d1x*d2y - d2x*d1y;
}
void Swap(int &a, int &b)
{
    if (a>b)
    {
        int t=a;
        a=b;
        b=t;
    }
}
int main (void)
{
    int n, i, cross, maxx, minx, maxy, miny, maxn, minn, countn=0;
    while (scanf("%d", &n)==1&&n)
    {
        maxx=maxy=-INF;
        minx=miny=INF;
        //点按顺时针给出
        for (i=1; i<=n; i++)
        {
            scanf("%d %d", &pt[i].x, &pt[i].y);
            if (maxx<pt[i].x) maxx=pt[i].x;
            if (maxy<pt[i].y) maxy=pt[i].y;
            if (minx>pt[i].x) minx=pt[i].x;
            if (miny>pt[i].y) miny=pt[i].y;
        }
        pt[n+1]=pt[1];
        pt[n+2]=pt[2];
        pt[n+3]=pt[3];
        pt[n+4]=pt[4];
        //求每条线段的转向
        for (i=1; i<=n+1; i ++)
        {
            cross = det(pt[i],pt[i+1], pt[i+1], pt[i+2]);
            if (cross<0)
                turn_right[i+1]=true;
            else turn_right[i+1]=false;
        }
        //两条边连续右转的为凸处,只有此时才可影响“核”肯恩存在的范围
        for (i=2; i<= n+1; i++)
            if (turn_right[i] && turn_right[i+1])
            {
                if (pt[i].x==pt[i+1].x)
                {
                    minn=pt[i].y;
                    maxn=pt[i+1].y;
                    Swap(minn, maxn);
                    if (minn>miny) miny=minn;
                    if (maxn<maxy) maxy=maxn;
                }
                else
                {
                    minn=pt[i].x;
                    maxn=pt[i+1].x;
                    Swap(minn, maxn);
                    if (minn>minx) minx=minn;
                    if (maxn<maxx) maxx=maxn;
                }
            }
        if (minx<=maxx && miny<=maxy)
            printf("Floor #%d\nSurveillance is possible.\n\n", ++countn);
        else printf("Floor #%d\nSurveillance is impossible.\n\n", ++countn);
    }
    return 0;
}

三角形的内外垂心

//定义点
struct point
{
	double x, y;
};
typedef struct point point;

//定义直线
struct line
{
	point a, b;
};
typedef struct line line;
//两点距离
double distance(point p1, point p2)
{
	return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
}
//两直线求交点
point intersection(line u, line v)
{
	point ret = u.a;
	double t = ((u.a.x - v.a.x)*(v.a.y - v.b.y) - (u.a.y - v.a.y)*(v.a.x - v.b.x))
		/ ((u.a.x - u.b.x)*(v.a.y - v.b.y) - (u.a.y - u.b.y)*(v.a.x - v.b.x));
	ret.x += (u.b.x - u.a.x)*t;
	ret.y += (u.b.y - u.a.y)*t;
	return ret;
}
//求三角形的外心
point circumcenter(point a, point b, point c)
{
	line u, v;
	u.a.x = (a.x + b.x) / 2;
	u.a.y = (a.y + b.y) / 2;
	u.b.x = u.a.x - a.y + b.y;
	u.b.y = u.a.y + a.x - b.x;
	v.a.x = (a.x + c.x) / 2;
	v.a.y = (a.y + c.y) / 2;
	v.b.x = v.a.x - a.y + c.y;
	v.b.y = v.a.y + a.x - c.x;
	return intersection(u, v);
}


//求三角形内心
point incenter(point a, point b, point c)
{
	line u, v;
	double m, n;
	u.a = a;
	m = atan2(b.y - a.y, b.x - a.x);
	n = atan2(c.y - a.y, c.x - a.x);
	u.b.x = u.a.x + cos((m + n) / 2);
	u.b.y = u.a.y + sin((m + n) / 2);
	v.a = b;
	m = atan2(a.y - b.y, a.x - b.x);
	n = atan2(c.y - b.y, c.x - b.x);
	v.b.x = v.a.x + cos((m + n) / 2);
	v.b.y = v.a.y + sin((m + n) / 2);
	return intersection(u, v);
}
//求三角形垂心
point perpencenter(point a, point b, point c)
{
	line u, v;
	u.a = c;
	u.b.x = u.a.x - a.y + b.y;
	u.b.y = u.a.y + a.x - b.x;
	v.a = b;
	v.b.x = v.a.x - a.y + c.y;
	v.b.y = v.a.y + a.x - c.x;
	return intersection(u, v);
}

费马点

模拟退火板题

 //计算三角形费马点
    //返回:到三角形三顶点距离之和最小的点
    Point fermentPoint()
    {
        Point u, v;
        double step = fabs(a.x) + fabs(a.y) + fabs(b.x) + fabs(b.y) + fabs(c.x) + fabs(c.y);
        int i, j, k;
        u.x = (a.x + b.x + c.x) / 3;
        u.y = (a.y + b.y + c.y) / 3;
        while (step > eps)
        {
            for (k = 0; k < 10; step /= 2, k ++)
            {
                for (i = -1; i <= 1; i ++)
                {
                    for (j =- 1; j <= 1; j ++)
                    {
                        v.x = u.x + step * i;
                        v.y = u.y + step * j;
                        if (getdis(u,a) + getdis(u,b) + getdis(u,c) > getdis(v,a) + getdis(v,b) + getdis(v,c))
                            u = v;
                    }
                }
            }
        }
        return u;
    }
古典几何

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Best KeyBoard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值