题目大意:输入 A , O , B 三个点的坐标,输出 K1 , K2 , K3 分别为角 AOB 四等分线上的点

题目分析:吐了吐了,这个题想到了一种解法,但是在实现的时候被高中的向量知识卡住了,要是这个题能过的话这次的红包应该能领不少呜呜呜

说回题目,借题目的图一用:

等分点 list python 什么是四等分点_#include

为了方便讲解,就将三条四等分线从左到右称为 XP , XC , XQ ,其中点 O 被我替换成了点 X

一开始想过可以求出角 AOB 的大小,然后除以四,每次将直线 XA 沿着点 X 旋转这么个角度就行了,不得不说思路很好,实现很难,放弃

接下来就想,既然是四等分点,求两次角平分线不就行了,那么我们可以先求出 XA 和 XB 的角平分线 XC ,然后再求出 XC 和 XA 的角平分线就是 XP 了,同理求出 XQ ,有了这个三个四等分线的直线方程,再令其与直线 AB 求交点,求出来的就是答案了

求角平分线有一种非常简单的方法,以 XA 和 XB 为例,可以先求出 XA 和 XB 代表的单位向量,根据向量的加法的特殊性质, XC 恰好就是 XA + XB ,这样一来题目就变的很简单了

好巧不巧,之前一直在用的 kuangbin 大牛的几何模板中,恰好有一个函数就是可以直接求单位向量的

需要注意的地方是,一开始是直线 XA ,其向量就是 ( OA - OX ) ,这里的 O 就是坐标原点

还有一点就是,直接这样求出来的 XC 是单位向量!!需要借助点 X 转换回 XC 这条直线才能进行后续操作,这里需要借助的知识就是,知道单位向量和直线上的一个点的坐标后如何得到直线方程,因为点 X 肯定在直线上的,所以点 X + XC 肯定也是在直线上,两点确定一条直线,这样直线得方程就确定好了

剩下的就是调用模板里的函数了

代码:
 

#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<unordered_map>
using namespace std;

typedef long long LL;

typedef unsigned long long ull;

const int inf=0x3f3f3f3f;

const int N=1e5+100;

const double eps = 1e-10;

int sgn(double x){
	if(fabs(x) < eps)return 0;
	if(x < 0)return -1;
	else return 1;
}

struct Point{
	double x,y;
	Point(){}
	Point(double _x,double _y){
		x = _x;
		y = _y;
	}
	void input(){
		scanf("%lf%lf",&x,&y);
	}
	void output(){
		printf("%.10f %.10f\n",x,y);
	}
	bool operator == (Point b)const{
		return sgn(x-b.x) == 0 && sgn(y-b.y) == 0;
	}
	bool operator < (Point b)const{
		return sgn(x-b.x)== 0?sgn(y-b.y)<0:x<b.x;
	}
	Point operator -(const Point &b)const{
		return Point(x-b.x,y-b.y);
	}
	//叉积
	double operator ^(const Point &b)const{
		return x*b.y - y*b.x;
	}
	//点积
	double operator *(const Point &b)const{
		return x*b.x + y*b.y;
	}
	//返回长度
	double len(){
		return hypot(x,y);//库函数
	}
	//返回两点的距离
	double distance(Point p){
		return hypot(x-p.x,y-p.y);
	}
	Point operator +(const Point &b)const{
		return Point(x+b.x,y+b.y);
	}
	Point operator *(const double &k)const{
		return Point(x*k,y*k);
	}
	Point operator /(const double &k)const{
		return Point(x/k,y/k);
	}
	//`化为长度为r的向量`
	Point trunc(double r){
		double l = len();
		if(!sgn(l))return *this;
		r /= l;
		return Point(x*r,y*r);
	}
};

struct Line{
	Point s,e;
	Line(){}
	Line(Point _s,Point _e){
		s = _s;
		e = _e;
	}
	bool operator ==(Line v){
		return (s == v.s)&&(e == v.e);
	}
	void adjust(){
		if(e < s)swap(s,e);
	}
	//求线段长度
	double length(){
		return s.distance(e);
	}
	//`点和直线关系`
	//`1  在左侧`
	//`2  在右侧`
	//`3  在直线上`
	int relation(Point p){
		int c = sgn((p-s)^(e-s));
		if(c < 0)return 1;
		else if(c > 0)return 2;
		else return 3;
	}
	// 点在线段上的判断
	bool pointonseg(Point p){
		return sgn((p-s)^(e-s)) == 0 && sgn((p-s)*(p-e)) <= 0;
	}
	//`两向量平行(对应直线平行或重合)`
	bool parallel(Line v){
		return sgn((e-s)^(v.e-v.s)) == 0;
	}
	//`两线段相交判断`
	//`2 规范相交`
	//`1 非规范相交`
	//`0 不相交`
	int segcrossseg(Line v){
		int d1 = sgn((e-s)^(v.s-s));
		int d2 = sgn((e-s)^(v.e-s));
		int d3 = sgn((v.e-v.s)^(s-v.s));
		int d4 = sgn((v.e-v.s)^(e-v.s));
		if( (d1^d2)==-2 && (d3^d4)==-2 )return 2;
		return (d1==0 && sgn((v.s-s)*(v.s-e))<=0) ||
			(d2==0 && sgn((v.e-s)*(v.e-e))<=0) ||
			(d3==0 && sgn((s-v.s)*(s-v.e))<=0) ||
			(d4==0 && sgn((e-v.s)*(e-v.e))<=0);
	}
	//`直线和线段相交判断`
	//`-*this line   -v seg`
	//`2 规范相交`
	//`1 非规范相交`
	//`0 不相交`
	int linecrossseg(Line v){
		int d1 = sgn((e-s)^(v.s-s));
		int d2 = sgn((e-s)^(v.e-s));
		if((d1^d2)==-2) return 2;
		return (d1==0||d2==0);
	}
	//`两直线关系`
	//`0 平行`
	//`1 重合`
	//`2 相交`
	int linecrossline(Line v){
		if((*this).parallel(v))
			return v.relation(s)==3;
		return 2;
	}
	//`求两直线的交点`
	//`要保证两直线不平行或重合`
	Point crosspoint(Line v){
		double a1 = (v.e-v.s)^(s-v.s);
		double a2 = (v.e-v.s)^(e-v.s);
		return Point((s.x*a2-e.x*a1)/(a2-a1),(s.y*a2-e.y*a1)/(a2-a1));
	}
	//点到直线的距离
	double dispointtoline(Point p){
		return fabs((p-s)^(e-s))/length();
	}
	//点到线段的距离
	double dispointtoseg(Point p){
		if(sgn((p-s)*(e-s))<0 || sgn((p-e)*(s-e))<0)
			return min(p.distance(s),p.distance(e));
		return dispointtoline(p);
	}
	//`返回线段到线段的距离`
	//`前提是两线段不相交,相交距离就是0了`
	double dissegtoseg(Line v){
		return min(min(dispointtoseg(v.s),dispointtoseg(v.e)),min(v.dispointtoseg(s),v.dispointtoseg(e)));
	}
};

int main()
{
#ifndef ONLINE_JUDGE
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
#endif
//	ios::sync_with_stdio(false);
	Point A,B,X;
	A.input(),X.input(),B.input();
	Point OA=(A-X).trunc(1);
	Point OB=(B-X).trunc(1);
	Point OC=(OA+OB).trunc(1);
	Point OP=OA+OC;
	Point OQ=OB+OC;
	Line AB(Line(A,B));
	AB.crosspoint(Line(OP+X,X)).output();
	AB.crosspoint(Line(OC+X,X)).output();
	AB.crosspoint(Line(OQ+X,X)).output();
	




	
	





    return 0;
}