计算几何(梅涅劳斯定理) - Triangle Hazard - UVA 12165
题意:
如 上 图 , 给 定 △ P Q R 的 三 个 顶 点 坐 标 以 及 6 个 比 例 m 1 , m 2 , . . . , m 6 , 如上图,给定\triangle PQR的三个顶点坐标以及6个比例m_1,m_2,...,m_6, 如上图,给定△PQR的三个顶点坐标以及6个比例m1,m2,...,m6,
求 出 A 、 B 、 C 三 个 顶 点 的 坐 标 。 求出A、B、C三个顶点的坐标。 求出A、B、C三个顶点的坐标。
输入:
T 组 测 试 数 据 , T组测试数据, T组测试数据,
每 组 数 据 首 行 包 括 6 个 浮 点 数 , 依 次 表 示 P 、 Q 、 R 的 横 纵 坐 标 , P x , P y , Q x , Q y , R x , R y 。 每组数据首行包括6个浮点数,依次表示P、Q、R的横纵坐标,P_x,P_y,Q_x,Q_y,R_x,R_y。 每组数据首行包括6个浮点数,依次表示P、Q、R的横纵坐标,Px,Py,Qx,Qy,Rx,Ry。
第 二 行 包 括 6 个 整 数 , m 1 , m 2 , . . . , m 6 第二行包括6个整数,m_1,m_2,...,m_6 第二行包括6个整数,m1,m2,...,m6
输出:
6 个 浮 点 数 , 依 次 表 示 A 、 B 、 C 的 横 纵 坐 标 。 6个浮点数,依次表示A、B、C的横纵坐标。 6个浮点数,依次表示A、B、C的横纵坐标。
Sample Input
3
4467.61586728 8492.59551366 7060.96479020 6775.46633005 6725.89311907 9028.87449315
11 56 38 97 49 60
5779.32806104 1918.19337634 7490.69623286 4845.34535926 6419.53729066 4864.56878239
18 80 56 87 58 59
8991.93033007 6724.32910758 7219.48100000 7527.95330769 8549.92222645 3068.19948096
13 86 11 44 20 35
Sample Output
9231.81800000 9623.96300000 3537.20000000 9108.65000000 7337.89000000 4913.10199999
7424.76700001 9490.84399999 4757.24799999 170.01100001 9262.77299999 4813.54299999
8242.99300000 529.39300000 9373.35300000 6551.39300000 6655.90700000 9417.10200000
数据范围:
0 < N < 25001 , 0 ≤ P x , P y , Q x , Q y , R x , R y ≤ 10000 , m 1 < m 2 , m 3 < m 4 , m 5 < m 6 0 < N < 25001,0 ≤ P_x, P_y, Q_x, Q_y, R_x, R_y ≤ 10000,m_1 < m_2, m_3 < m_4 ,m_5 < m_6 0<N<25001,0≤Px,Py,Qx,Qy,Rx,Ry≤10000,m1<m2,m3<m4,m5<m6
Time limit:3000 ms
分析:
梅涅劳斯定理:
当 一 条 直 线 交 △ A B C 三 边 所 在 的 直 线 B C 、 A C 、 A B 分 别 于 点 D 、 E 、 F 时 , 则 有 : 当一条直线交\triangle ABC三边所在的直线BC、AC、AB分别于点D、E、F时,则有: 当一条直线交△ABC三边所在的直线BC、AC、AB分别于点D、E、F时,则有:
A F F B × B D C D × C E E A = 1 \frac{AF}{FB}×\frac{BD}{CD}×\frac{CE}{EA}=1 FBAF×CDBD×EACE=1
记忆口诀:顶点到交点,交点回顶点。
本 题 中 本题中 本题中
对
于
A
的
坐
标
,
若
我
们
知
道
R
A
P
R
的
值
,
就
能
够
通
过
向
量
得
到
A
点
的
坐
标
,
B
、
C
同
理
。
对于A的坐标,若我们知道\frac{RA}{PR}的值,就能够通过向量得到A点的坐标,B、C同理。
对于A的坐标,若我们知道PRRA的值,就能够通过向量得到A点的坐标,B、C同理。
我 们 将 △ A B C 分 成 三 块 : △ A B P 、 △ A C R 、 △ B C Q 我们将\triangle ABC分成三块:\triangle ABP、\triangle ACR、\triangle BCQ 我们将△ABC分成三块:△ABP、△ACR、△BCQ
对 △ A B P 、 △ B C Q 、 △ A C R 分 别 应 用 梅 涅 劳 斯 定 理 : 对\triangle ABP、 \triangle BCQ、\triangle ACR分别应用梅涅劳斯定理: 对△ABP、△BCQ、△ACR分别应用梅涅劳斯定理:
A R R P × P Q Q B × B F F A = 1 \frac{AR}{RP}×\frac{PQ}{QB}×\frac{BF}{FA}=1 RPAR×QBPQ×FABF=1
B P P Q × Q R R C × C D D B = 1 \frac{BP}{PQ}×\frac{QR}{RC}×\frac{CD}{DB}=1 PQBP×RCQR×DBCD=1
C Q Q R × R P P A × A E E C = 1 \frac{CQ}{QR}×\frac{RP}{PA}×\frac{AE}{EC}=1 QRCQ×PARP×ECAE=1
即 : 即: 即:
A R R P × P Q P Q + B P = m 5 m 6 = k 1 ① \frac{AR}{RP}×\frac{PQ}{PQ+BP}=\frac{m_5}{m_6}=k_1\qquad ① RPAR×PQ+BPPQ=m6m5=k1①
B P P Q × Q R Q R + Q C = m 1 m 2 = k 2 ② \\ \ \\\frac{BP}{PQ}×\frac{QR}{QR+QC}=\frac{m_1}{m_2}=k_2\qquad ② PQBP×QR+QCQR=m2m1=k2②
C Q Q R × R P R P + R A = m 3 m 4 = k 3 ③ \\ \ \\ \frac{CQ}{QR}×\frac{RP}{RP+RA}=\frac{m_3}{m_4}=k_3\qquad ③ QRCQ×RP+RARP=m4m3=k3③
设 R A → = x 1 P R → , B P → = x 2 P Q → , Q C → = x 3 R Q → 设\overrightarrow{RA}=x_1\overrightarrow{PR},\overrightarrow{BP}=x_2\overrightarrow{PQ},\overrightarrow{QC}=x_3\overrightarrow{RQ} 设RA=x1PR,BP=x2PQ,QC=x3RQ
由 ① 、 ② 、 ③ 得 : 由①、②、③得: 由①、②、③得:
x 1 = k 1 ( 1 + x 2 ) x_1=k_1(1+x_2) x1=k1(1+x2)
x 2 = k 2 ( 1 + x 3 ) x_2=k_2(1+x_3) x2=k2(1+x3)
x 3 = k 3 ( 1 + x 1 ) x_3=k_3(1+x_1) x3=k3(1+x1)
由 此 我 们 解 得 : 由此我们解得: 由此我们解得:
x 1 = k 1 + k 1 k 2 + k 1 k 2 k 3 1 − k 1 k 2 k 3 x_1=\frac{k_1+k_1k_2+k_1k_2k_3}{1-k_1k_2k_3} x1=1−k1k2k3k1+k1k2+k1k2k3
x 2 = k 2 + k 2 k 3 + k 1 k 2 k 3 1 − k 1 k 2 k 3 x_2=\frac{k_2+k_2k_3 +k_1k_2k_3}{1-k_1k_2k_3} x2=1−k1k2k3k2+k2k3+k1k2k3
x 3 = k 3 + k 1 k 3 + k 1 k 2 k 3 1 − k 1 k 2 k 3 x_3=\frac{k_3+k_1k_3+k_1k_2k_3}{1-k_1k_2k_3} x3=1−k1k2k3k3+k1k3+k1k2k3
注意:
我 们 重 载 向 量 与 常 数 相 乘 时 , 常 数 项 在 后 , 因 此 注 意 运 算 符 不 满 足 交 换 律 。 我们重载向量与常数相乘时,常数项在后,因此注意运算符不满足交换律。 我们重载向量与常数相乘时,常数项在后,因此注意运算符不满足交换律。
代码:
#include<cstring>
#include<iostream>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const double eps=1e-5;
const double pi=acos(-1.0);
struct Point
{
double x,y;
Point(double x=0,double y=0) : x(x), y(y) {}
};
//点与向量
typedef Point Vector;
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); }
int T;
int m[10];
Point P,Q,R;
double cal(double k1,double k2,double k3)
{
return (k1+k1*k2+k1*k2*k3)/(1-k1*k2*k3);
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%lf%lf%lf%lf%lf%lf",&P.x,&P.y,&Q.x,&Q.y,&R.x,&R.y);
for(int i=1;i<=6;i++) scanf("%d",&m[i]);
double k1=1.0*m[5]/m[6], k2=1.0*m[1]/m[2], k3=1.0*m[3]/m[4];
double x1=cal(k1,k2,k3), x2=cal(k2,k3,k1), x3=cal(k3,k1,k2);
Point A=R+(R-P)*x1, B=P+(P-Q)*x2, C=Q+(Q-R)*x3;
printf("%.8lf %.8lf %.8lf %.8lf %.8lf %.8lf\n",A.x,A.y,B.x,B.y,C.x,C.y);
}
return 0;
}