UVA-11437 Triangle Fun(梅涅勞斯定理)(三等分點)


題意:如下是一個三角形ABC.\(點D,E和F是三角形ABC的三等分點,\)\(三角形PQR\)的面積。

分析:三等分點的坐標可以推導出來,比如求D的坐標,D的坐標為\((\frac{2 * B.x + C.x}{3}, \frac{2 * B.y + C.y}{3})\),然后求出\(三個交點P, R, Q\),求出向量\(\vec{pr}\)\(\vec{pq}\)的夾角,然后利用公式\(\frac{1}{2}*|pr|*|pq|*sin\angle{RPQ}\)求出三角形面積。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>
#include <algorithm>

using namespace std;

const double eps = 1e-10;
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); }

double Dot(Vector A, Vector B) { return A.x * B.x + A.y * B.y; }
double Cross(Vector A, Vector B) { return A.x * B.y - A.y * B.x; }
double Length(Vector A) { return sqrt(Dot(A, A)); }

Vector Normal(Vector A)
{
	double L = Length(A);
	return Vector(-A.y / L, A.x / L);
}

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

bool operator<(const Point& a, const Point& b)
{
	return dcmp(a.x - b.x) < 0 || dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) < 0;
}

bool operator == (const Point& a, const Point& b)
{
	return dcmp(a.x - b.x) == 0 && dcmp(a.y - b.y) == 0;
}

Point GetLineIntersection(Point P, Vector v, Point Q, Vector w)
{
	Vector u = P - Q;
	double t = Cross(w, u) / Cross(v, w);
	return P + v * t;
}

struct Line {
	Point p;
	Vector v;
	Line(Point p, Vector v) :p(p), v(v) { }
	//直線上的點坐標
	Point point(double t) {
		return p + v * t;
	}
	//平移直線d距離
	Line move(double d) {
		return Line(p + Normal(v) * d, v);
	}
};

Point GetLineIntersection(Line a, Line b)
{
	return GetLineIntersection(a.p, a.v, b.p, b.v);
}

double angle(Vector v)
{
	return atan2(v.y, v.x);
}

void out(Point a)
{
	cout << a.x << a.y << endl;
}

int main()
{
	//freopen("in.txt", "r", stdin);
	int t;
	scanf("%d", &t);
	for (int i = 1; i <= t; ++i)
	{
		double ax, ay, bx, by, cx, cy;
		scanf("%lf%lf%lf%lf%lf%lf", &ax, &ay, &bx, &by, &cx, &cy);
		Point A(ax, ay), B(bx, by), C(cx, cy);

		//f點(A, B的三等分點)
		Point F((2 * A.x + B.x) / 3, (2 * A.y + B.y) / 3);

		//d點(B, C的三等分點)
		Point D((2 * B.x + C.x) / 3, (2 * B.y + C.y) / 3);

		//e點(A, C的三等分點)
		Point E((2 * C.x + A.x) / 3, (2 * C.y + A.y) / 3);

		//直線ad
		Line ad(A, A - D);
		//直線be
		Line be(B, B - E);
		//直線cf
		Line cf(C, C - F);

		Point p = GetLineIntersection(ad, be);
		Point q = GetLineIntersection(be, cf);
		Point r = GetLineIntersection(ad, cf);

		Line pr(p, p - r);
		Line pq(p, p - q);

		double ang2 = angle(pq.v);
		double ang1 = angle(pr.v) - ang2;

		//pr和pq的夾角
		double ang = acos(Dot(pr.v, pq.v) / Length(pr.v) / Length(pq.v));

		//余弦定理
		double s = 1.0 / 2.0 * Length(pr.v) * Length(pq.v) * sin(ang);

		printf("%.0lf\n", s);
	}

	return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM