赞
踩
“最近听过感触最深的一句话:思想能够到达的地方比光速还要快!月球到了!太阳到了!你能知道的就是你能到达的,所以我们才要扩充我们的知识面,你要知道你才能到啊!
”
太阳之外是什么?不知道了?到不了了,原因是什么?因为无知!因为我们把时间和精力花在了喝酒、吃饭、K歌。
如果你有足够大的勇气去说再见,放弃一切娱乐,从现在开始每天学习,生活一定会奖励你一个新的开始。人生最难的是改变自己。凤凰涅槃浴火重生的人都很了不起。
const double eps = 1e-8;bool EQ(double a, double b) { return fabs(a - b) }
int threeValue(double d) { if (fabs(d) return 0; return d > 0 ? 1 : -1;}
double v = -0.0000000001; printf("%.2lf\n", v);
double v = -0.0000000001; if(threeValue(v) == 0) { v = fabs(v); } printf("%.2lf\n", v);
typedef double Type;class Point2D {private: Type x, y;public: Point2D(Type _x, Type _y) : x(_x), y(_y) {} ...};
typedef Point2D Vector2D;
加
Point2D Point2D::operator+(const Point2D& other) const { return Point2D(x + other.x, y + other.y);}
减
Point2D Point2D::operator-(const Point2D& other) const { return Point2D(x - other.x, y - other.y);}
乘
Point2D Point2D::operator *(const double &k) const { return Point2D(x * k, y * k);}
除
double Vector2D::len() { return sqrt(x*x + y*y);}
Point2D a(0, 2), b(3, 4);double dist = (b - a).len();
Point2D Vector2D::normalize() { double l = len(); if (threeValue(l)) { x /= l, y /= l; } return *this;}
Type Point2D::operator*(const Point2D& other) const { return x*other.x + y*other.y;}
Type Point2D::X(const Point2D& other) const { return x*other.y - y*other.x;}
1),则 在 左侧(参考点A);
2),则 和 共线(参考点B);
3),则 在 右侧(参考点C);
所以,只要两个点分别和对应向量做叉乘,再将结果相乘,如果值大于0,则代表同侧;小于零代表异侧;
叉乘还代表了两个向量组成的平行四边形的面积,有公式:
Point2D Point2D::turn(double theta) { double costheta = cos(theta); double sintheta = sin(theta); return Point2D( x*costheta - y*sintheta, x*sintheta + y*costheta );}
enum SegCrossType { SCT_NONE = 0, // 不相交 SCT_CROSS = 1, // 相交于内部 SCT_ENDPOINT_ON = 2, // 其中一条线段的端点在另一条上};
class Segment2D { Point2D s, t;public: ...};
Type Segment2D::cross(const Point2D& p) const { return (p - s).X(t - s);}bool Segment2D::lineCross(const Segment2D& other) const { return threeValue(cross(other.s)) * threeValue(cross(other.t)) == -1;}
cross
实现的是点 在向量 的哪边;lineCross
判断两个点是否在向量的两边(通过取三值函数后,相乘为 -1 来实现);bool Segment2D::pointOn(const Point2D& p) const { // 满足两个条件: // 1.叉乘为0, (p-s)×(t-s) == 0 // 2.点乘为-1或0,(p-s)*(p-t) <= 0 return cross(p) == 0 && (p - s)*(p - t) <= 0;}
SegCrossType Segment2D::segCross(const Segment2D& other) { if (this->lineCross(other) && other.lineCross(*this)) { // 两次跨立都成立,则必然相交与一点 return SCT_CROSS; } // 任意一条线段的某个端点是否在其中一条线段上,四种情况 if (pointOn(other.s) || pointOn(other.t) || other.pointOn(s) || other.pointOn(t)) { return SCT_ENDPOINT_ON; } return SCT_NONE;}
struct Polygon { int n; Point2D p[MAXP]; double area();};double Polygon::area() { double sum = 0; p[n] = p[0]; for (int i = 0; i sum += p[i].X(p[i + 1]); return sum / 2;}
// 是否凸多边形bool Polygon::isConvex() { bool s[3] = { false, false, false }; p[n] = p[0], p[n + 1] = p[1]; for (int i = 0; i s[threeValue((p[i + 1] - p[i]) * (p[i + 2] - p[i])) + 1] = true; // 叉乘有左有右,肯定是凹的 if (s[0] && s[2]) return false; } return true;}
// 转成逆时针顺序void Polygon::convertToCounterClockwise() { if (area() >= 0) { return; } for (int i = 1; i <= n / 2; ++i) { Point2D tmp = p[i]; p[i] = p[n - i]; p[n - i] = tmp; }}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。