计算几何学(1)

//结构体表示点
struct Point{
    int x,y;
};

我们将既有大小又有方向的量称为“向量”。相对的,只有大小没有方向的量称为“标量”。这里,将向量考虑成从源点(0,0)指向对象点P(x,y)的有向线段。

//同时也完全可以用点的数据结构来表示向量
typedef Point Vector;

我们可以用包含两个点(起点p1和终点p2)的结构体或类来表示线段。这里要区分线段和直线,线段有始有终,而直线是通过两个点且长度无线的线。

struct Segment{
    Point p1,p2;
};
//直线数据结构的表示和线段相同(注意区别)
typedef Segment Line

紧接着就是圆的表示了,所谓确定圆心和半径可以确定一个,这里我们用类表示。

class Circle{
    public:
        Point c;
        double r;
        Circle(Point c=Point(),double r=0.0):c(c),r(r){}
};

多边形就是许多点组成的封闭图形,所以可以用点的序列来表示。

typedef vector<Point> Polygon;

向量的基本运算(通过坐标运算实现)

向量的运算共有三种:向量的和(sum)\underset{a}{\rightarrow}+\underset{b}{\rightarrow},向量的差(difference)\underset{a}{\rightarrow}-\underset{b}{\rightarrow},向量的标量倍(scalar multipliaction)k\underset{a}{\rightarrow}。以下我们将点和向量写成类的形式并附加上运算函数以及 求向量大小和范数的函数。

#define EPS (1e-10)
#define equals(a,b) (fabs((a)-(b)) < EPS) 
class Point{
	public:

		double x,y;
		Point(double x=0,double y=0):x(x),y(y){}
		
		Point operator + (Point p){
			return Point(x+p.x,y+p.y);
		}

		Point operator - (Point p){
			return Point(x-p.x,y-p.y);
		}

		Point operator * (double a){
		    return Point(a*x,a*y);
		}

		Point operator / (double a){
			return Point(x/a,y/a);
		}
		
		double abs(){
			return sqrt(norm());
		} 

		double norm(){
			return x*x+y*y;
		}
		//递增的顺序
		bool operator < (const Point &p) const{
			return x!=p.x?x<p.x:y<p.y;
		}
		//有精度误差(在规定的精度范围内都视为相同)
		bool operator == (const Point &p) const{
			return fabs(x-p.x)<EPS&&fabs(y-p.y)<EPS;
		}
}; 

为了以后解决几何的相关问题,向量的内积和外积必不可少。

设向量a、b的夹角θ(0≤θ≤180),那么a,b的内积(dot product)a\cdot b=|a||b|cos\theta。如图所示(手画一张):

//向量a和b的内积a·b=|a||b|cosθ
double dot(Vector a,Vector b){
	return a.x*b.x+a.y*b.y;
} 

a,b的外积(cross product)|a\cdot b|=|a||b|sin\theta。两个向量的外积是一个具有大小和方向的向量。如下图所示,外积的方向与a,b所在的平面垂直,且满足右手螺旋定则。

//向量a和b的外积|a×b|=|a||b|sinθ
double cross(Vector a,Vector b){
	return a.x*b.y-a.y*b.x;
} 

可以继续噢——计算几何学(2)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值