索引:
double Dot(Vector,Vector) -> 求两个点的点积,点积可用于判断一个点是否在一个线段的范围内,+不在,-在
double length(Vector) -> 利用点积求向量的长度
double Angle(Vector,Vector) -> 利用点积和长度以及余弦定理求两个向量之间的夹角
double Cross(Vector,Vector) -> 求两个向量之间的叉积,叉积为0,两条直线平行
Vector Rotate(Vector,double) -> 向量旋转
Point GetLineIntersection(Point,Vector,Point,Vector) -> 求两个直线的交点(有前提)
下面是求三角形三个角的三等分点交点的求法 #include <iostream> #include <cmath> #include <cstdio> #include <algorithm> using namespace std; typedef long long ll; using namespace std; //const int mod = 1e9 + 7; struct Point { double x,y; Point(double x=0,double y=0):x(x),y(y) {} }; typedef Point Vector; //C++的运算符重载 Vector operator +(Vector A,Vector B) //向量 + 向量 = 向量 ,向量 + 点 = 点 { return Vector(A.x + B.x , A.y + B.y); } Vector operator -(Point A,Point B) //点 - 点 = 向量 { return Vector(A.x - B.x , A.y - B.y); } Vector operator *(Vector A, double p) //向量 * 数 = 向量 { return Vector(A.x * p, A.y * p); } Vector operator /(Vector A, double p) //向量/数 = 向量 { return Vector(A.x/p ,A.y/p); } //点积:两个向量的长度 * 他们夹角的余弦 = (在平面坐标系下)XA * XB + YA * YB double Dot(Vector A , Vector B) //求点积 { return A.x * B.x + A.y * B.y; } double Length(Vector A) //利用点积求长度 { return sqrt(Dot(A,A)); } //利用点积平面坐标下的公式,以及点积求出的长度,求出两个向量之间的夹角 double Angle(Vector A,Vector B) { return acos(Dot(A, B) / Length(A) / Length(B)); } //叉积:(在平面坐标系下)XA * YB - XB * YA //叉积平行是0,在左边是正,右边是负 double Cross(Vector A , Vector B) //叉积求的是两个向量的叉积 { return A.x * B.y - A.y * B.x; } //向量旋转:向量可以绕起点旋转,公式是:x' = x * cosa - y * sina // y' = x * sina + y * cosa //其中a是逆时针旋转的角 Vector Rotate(Vector A, double rad) //rad 是 弧度 (向量的逆时针旋转,如果rad是负数,则是顺时针旋转) { return Vector(A.x * cos(rad) - A.y * sin(rad) , A.x * sin(rad) + A.y * cos(rad)); } /* 直线的参数表示: 直线可以用直线上一点P0和方向向量v表示(虽然这个向量的大小没什么用处)。直线上所有点P满足 P = P0 + tv,其中t称为参数。 如果已知直线上的两个不同点A,B,则方向向量是B - A,所以参数方程是A + (B - A)t; 参数方程最方便的地方在于:直线、射线、线段的方程都是一样的,区别在于参数:直线t没有范围,射线t>0,线段t在0~1之间 */ /* 直线交点: 两条直线分别是:P + tv 和 Q + tw 调用前要确保两条直线P+tv 和Q + tw有唯一交点。当且仅当Cross(v,w)非0; */ //调用前确保两条直线相交,当且仅Cross(v,w)非零。计算两条直线P + tv 和 Q + tw 的交点 Point GetLineIntersection(Point P,Vector v,Point Q,Vector w) //?????? //线段交点:参数分别是:线段1的起点P,以P为起点的向量v,线段2的起点Q,以Q为起点的向量w { Vector u = P - Q; double t = Cross(w, u)/ Cross(v, w); //叉积 // 第二条直线上的参数: // double t2= Cross(v, u) / Cross(v, w); // cout << (P+v*t).x << " " << (P+v*t).y << " ddd" << endl; return P + v * t; } //点到直线的距离 double DistanceToLine(Point P,Point A,Point B) //利用叉积的定义,即用平行四边形除以底 { Vector v1 = B - A ; Vector v2 = P - A ; return fabs(Cross(v1, v2)) / Length(v1); } Point getD(Point A,Point B,Point C) //求角三等分交点 { Vector v1 = C - B; double a1 = Angle(A - B, v1); //计算B角的角度 v1 = Rotate(v1, a1/3); //求出1/3B角 Vector v2 = B - C ; double a2 = Angle(A - C , v2); //计算出C角的角度 v2 = Rotate(v2, -a2/3) ; // 负数代表顺时针旋转 return GetLineIntersection(B,v1,C,v2); } int main() { int T; scanf("%d",&T); Point A,B,C,D,E,F; while(T--) { scanf("%lf %lf %lf %lf %lf %lf",&A.x, &A.y ,&B.x ,&B.y ,&C.x ,&C.y); D = getD(A, B, C); E = getD(B, C, A); F = getD(C, A, B); printf("%.6lf %.6lf %.6lf %.6lf %.6lf %.6lf\n",D.x ,D.y ,E.x ,E.y, F.x ,F.y); } return 0; }