标签:
公式描述:公式中a,b,c分别为三角形三边长,p为半周长,S为三角形的面积。
公式描述:公式中的直线方程为Ax+By+C=0,点P的坐标为(x0,y0)。但是直线方程不是够直接。推荐使用方法二。
有以下四种情况:
以下是具体代码, 代码已经在 51 Nod 1298 圆与三角形 测试过了。
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define fst first
#define snd second
typedef __int64 LL;
//typedef long long LL;
typedef unsigned int uint;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int MAXN = 3 + 5;
const int MAXM = 600 + 5;
// 判断浮点数与0的大小关系
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) {}
} pc, p[MAXN];
typedef Point Vect;
/**
* 两点距离公式
*
*/
double getDist(const Point &p1, const Point &p2) {
int tx = p1.x - p2.x;
int ty = p1.y - p2.y;
return sqrt(tx * tx + ty * ty);
}
/**
* 由两点求向量
*
*/
Vect getVect(const Point& p1, const Point &p2) {
return Vect(p2.x - p1.x, p2.y - p1.y);
}
/**
* 求矢量叉积
* @param v1 [description]
* @param v2 [description]
* @return [description]
*/
double xmult(const Vect& v1, const Vect& v2) {
return v1.x * v2.y - v2.x * v1.y;
}
/**
* 矢量叉积求面积
*
*/
double getArea1(const Point &p0, const Point &p1, const Point &p2) {
Vect v1 = getVect(p0, p1);
Vect v2 = getVect(p0, p2);
return 0.5 * getVectProduct(v1, v2);
}
/**
* 海伦公式求面积
*
*/
double getArea2(const Point &p0, const Point &p1, const Point &p2) {
double p0p1 = getDist(p0, p1);
double p0p2 = getDist(p0, p2);
double p1p2 = getDist(p1, p2);
double x = (p0p1 + p0p2 + p1p2) / 2.0;
return sqrt(x * (x - p0p1) * (x - p0p2) * (x - p1p2));
}
/**
* 利用海伦公式或者叉积公式求点到直线的距离
* @param p0 [点]
* @param p1 [直线上的点1]
* @param p2 [直线上的点2]
* @return [点到直线的距离]
*/
double point2line(const Point &p0, const Point &p1, const Point &p2) {
double area = getArea1(p0, p1, p2);
// double area = getArea2(p0, p1, p2);
double p1p2 = getDist(p1, p2);
return 2 * area / p1p2;
}
/**
* 获取点到线段的最小距离
* @param p0 [点]
* @param p1 [线段端点1]
* @param p2 [线段端点2]
* @return [点到线段的距离]
*/
double point2lineSeg_Near(const Point &p0, const Point &p1, const Point &p2) {
double p0p1 = getDist(p0, p1);
double p0p2 = getDist(p0, p2);
double p1p2 = getDist(p1, p2);
// 点在线段上
if (sgn(p0p1 + p0p2 - p1p2) == 0) return 0;
// 线段两个端点p1,p2重合
if (sgn(p1p2) == 0) return p0p1;
// ∠p0p1p2 为直角或者钝角
if (p0p2 * p0p2 >= p0p1 * p0p1 + p1p2 * p1p2) return p0p1;
// ∠p0p2p1 为直角或者钝角
if (p0p1 * p0p1 >= p0p2 * p0p2 + p1p2 * p1p2) return p0p2;
// ∠p0p1p2 和 ∠p0p2p1 都是锐角,等价于求点到直线的距离
return point2line(p0, p1, p2);
}
/**
* 求点到线段的最长距离
* @param p0 [点]
* @param p1 [线段端点1]
* @param p2 [线段端点2]
* @return [最长距离]
*/
double point2lineSeg_Far(const Point &p0, const Point &p1, const Point &p2) {
double p0p1 = getDist(p0, p1);
double p0p2 = getDist(p0, p2);
return max(p0p1, p0p2);
}
int T;
double R;
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
scanf("%d", &T);
while (T --) {
scanf("%lf %lf %lf", &pc.x, &pc.y, &R);
for (int i = 0; i < 3; i ++) {
scanf("%lf %lf", &p[i].x, &p[i].y);
}
double mi[3], ma[3];
mi[0] = point2lineSeg_Near(pc, p[0], p[1]);
mi[1] = point2lineSeg_Near(pc, p[0], p[2]);
mi[2] = point2lineSeg_Near(pc, p[1], p[2]);
ma[0] = point2lineSeg_Far(pc, p[0], p[1]);
ma[1] = point2lineSeg_Far(pc, p[0], p[2]);
ma[2] = point2lineSeg_Far(pc, p[1], p[2]);
bool suc = false;
for (int i = 0; i < 3; i ++) {
if (sgn(mi[i] - R) <= 0 && sgn(ma[i] - R) >= 0) {
suc = true;
break;
}
}
puts(suc ? "Yes" : "No");
}
return 0;
}
判断三点共线的方法可以通过求斜率,求周长,求面积来判断。
故,只需要判断即可。
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define fst first
#define snd second
typedef __int64 LL;
//typedef long long LL;
typedef unsigned int uint;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int MAXN = 4 + 5;
const int MAXM = 600 + 5;
int sgn(double x) {
if (fabs(x) < eps) return 0;
if (x < 0) return -1;
else return 1;
}
struct Point {
double x, y, z;
};
typedef Point Vect;
int T;
Point pnts[MAXN];
/**
* 三维空间中两点求向量
*
*/
Vect getVect(const Point& p1, const Point& p2) {
Vect v;
v.x = p1.x - p2.x;
v.y = p1.y - p2.y;
v.z = p1.z - p2.z;
return v;
}
/**
* 求三维空间的两向量叉积 (v1 × v2)
*
*/
Vect xMulti(const Vect& v1, const Vect& v2) {
Vect v;
v.x = v1.y * v2.z - v1.z * v2.y;
v.y = v1.z * v2.x - v1.x * v2.z;
v.z = v1.x * v2.y - v1.y * v2.x;
return v;
}
/**
* 求三维空间中的两向量点积 (v1 · v2)
*
*/
double dotMulti(const Vect& v1, const Vect& v2) {
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
}
/**
* 求三维空间中三个向量的混合积 (v1 × v2)·(v3)
*
*/
double mixMulti(const Vect& v1, const Vect& v2, const Vect& v3) {
return dotMulti(xMulti(v1, v2), v3);
}
/**
* 判断四点是否共面
* 根据混合积求体积,判断体积是否为0
*/
bool isInArea(const Point& p1, const Point& p2, const Point& p3, const Point& p4) {
Vect p1p2, p1p3, p1p4;
p1p2 = getVect(p1, p2);
p1p3 = getVect(p1, p3);
p1p4 = getVect(p1, p4);
return sgn(mixMulti(p1p2, p1p3, p1p4)) == 0;
}
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
scanf("%d", &T);
while (T --) {
for (int i = 0; i < 4; i ++) {
scanf("%lf %lf %lf", &pnts[i].x, &pnts[i].y, &pnts[i].z);
}
bool ret = isInArea(pnts[0], pnts[1], pnts[2], pnts[3]);
puts(ret ? "Yes" : "No");
}
return 0;
}
#include <cmath>
#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w",stdout)
#define fst first
#define snd second
typedef __int64 LL;
//typedef long long LL;
typedef unsigned int uint;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const double eps = 1e-6;
const int MAXN = 4 + 5;
const int MAXM = 600 + 5;
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) {}
} pnts[MAXN];
typedef Point Vect;
Vect getVect(const Point& p1, const Point &p2) {
return Vect(p2.x - p1.x, p2.y - p1.y);
}
double xMulti(const Vect& v1, const Vect& v2) {
return v1.x * v2.y - v2.x * v1.y;
}
/**
* 判断线段是否相交
*
*/
bool segInter(const Point& p1, const Point& p2, const Point& p3, const Point& p4) {
return max(p1.x, p2.x) >= min(p3.x, p4.x) &&
max(p3.x, p4.x) >= min(p1.x, p2.x) &&
max(p1.y, p2.y) >= min(p3.y, p4.y) &&
max(p3.y, p4.y) >= min(p1.y, p2.y) &&
sgn(xMulti(getVect(p3, p2), getVect(p1, p2))) * sgn(xMulti(getVect(p4, p2), getVect(p1, p2))) <= 0 &&
sgn(xMulti(getVect(p1, p4), getVect(p3, p4))) * sgn(xMulti(getVect(p2, p4), getVect(p3, p4))) <= 0;
}
int T;
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif // ONLINE_JUDGE
scanf("%d", &T);
while(T --) {
for(int i = 0; i < 4; i ++) {
scanf("%lf %lf", &pnts[i].x, &pnts[i].y);
}
bool ret = segInter(pnts[0], pnts[1], pnts[2], pnts[3]);
puts(ret ? "Yes" : "No");
}
return 0;
}标签:
原文地址:http://blog.csdn.net/acmore_xiong/article/details/51899284