1.两点间的距离公式:
已知:平面上的两点的直角坐标分别为P1(x1,y1),P2(x2,y2),则P1和P2两点间的距离为
d=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2))
2.线段的中点坐标公式:
已知:平面上的两点的直角坐标分别为P1(x1,y1),P2(x2,y2),则线段P1P2的中点坐标为
x=(x1+x2)/2 y=(y1+y2)/2
3.直线的斜率公式:
已知:平面上的两点的直角坐标分别为P1(x1,y1),P2(x2,y2),则线段P1P2所在的直线的斜率为
k=(y2-y1)/(x2-x1)
4.直线的点斜式方程:
已知:直线过点P0(x0,y0),斜率为k,则该直线所在的方程为
y=k(x-x0)+y0=kx+y0-kx0=kx+b(与y轴交点的纵坐标:纵截距)
练习
1.已知:矩形上三点的坐标p1(x1,y1),p2(x2,y2),p3(x3,y3)
(1)求矩形另外一点的坐标p4(x4,y4)。
(2)判断点p(x,y)是在矩形内、矩形外还是在矩形的边上。
4. 2 线段的相交判断
1.叉积
已知:平面上的两点的直角坐标分别为p1(x1,y1),p2(x2,y2)则
(1)该两点相对坐标原点(0,0)的叉积为m=x1*y2-x2*y1
若m>0 则相对坐标原点,点p1在点p2的顺时针方向
若m<0 则相对坐标原点,点p1在点p2的逆时针方向
若m=0 则原点和p1、p2在一条直线上
(2)该两点相对点p0(x0,y0)的叉积为m=(x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)
若m>0 则相对p0点,点p1在点p2的顺时针方向
若m<0 则相对p0点,点p1在点p2的逆时针方向
若m=0 则p0和p1、p2在一条直线上
2.确定两条连续的有向线段p0p1和p1p2在pl点是向左转还是向右转
(1)计算叉积m=(x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)
(2)判断m
若m>0 则p1点向左拐
若m<0 则p1点向右拐
若m=0 则点p0、p1、p2在一条直线上
3.确定两条线段p1p2、p3p4是否相交
程序如下:
program xdxj;
type p=record
x, y:real
end;
var p1,p2,p3,p4:p;
function m(p1,p2,p0:p):real;
begin
m:=(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
end;
function max(a,b:real):real;
begin
if a>b then max:=a else max:=b;
end;
function min(a,b:real):real;
begin
if a<b then min:=a else min:=b;
end;
function across(p1,p2,p3,p4:p):boolean;
begin
if (max(p1.x,p2.x)>=min(p3.x,p4.x)) and
(max(p3.x,p4.x)>=min(p1.x,p2.x)) and
(max(p1.y,p2.y)>=min(p3.y,p4.y)) and
(max(p3.y, p4.y)>=min(p1.y,p2.y)) and
(m(p2,p3,p1)*m(p2,p4,p1)<0) and (m(p4,p1,p3)*m(p4,p2,p3)<0)
then across:=true else across:=false;
end;
begin
readln(p1.x,p1.y,p2.x,p2.y);
readln(p3.x,p3.y,p4.x,p4.y);
if across(p1,p2,p3,p4) then writeln('yes') else writeln('no');
end.
4.3寻找凸包算法
1.凸包的概念
一个点集Q=(p0,p1,p2...pn-1),它的凸包是一个最小的凸多边形P,且满足Q中的每个点或者在P的边界上,或者在P的内部。在直观上,我们可以把Q中的每个点看作露在板外的铁钉.那么凸包就是包含所有铁钉的一个拉紧的橡皮绳所构成的形状.
如图:
2.寻找凸包算法
算法如下(Graham算法):
1)求q中y坐标最小的点p0,若具有最小坐标的点有多个,则取最左边的点作为po.
2)对q中剩余的点按逆时针相对p0的极角排序,若有数个保留其中距p0最远的点
得到序列(p1,p2,...pn-1);
3)p0,p1,p2相继入栈
4)for i=3 to n-1 do
1) while 由次栈顶元素、栈顶元素和Pi所形成角不是向左转do栈顶元素出栈s;
2)pi入栈
5)打印按逆时针排列的栈中的各顶点
程序如下:
program tubao;
const maxn=500;
type p=record
x,y:real;
end;
var n,top:integer;
list:array[0..maxn]of p;
s:array[1..maxn] of integer;
f:text;
procedure swap(var a,b:p);
var t:p;
begin t:=a;a:=b;b:=t end;
function m(p1,p2,p0:p):real;
begin
m:=(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
end;
function comp(p1,p2:p):boolean;
var t:real;
begin
t:=m(p1,p2,list[0]);
if (t>0) or (t=0) and (sqr(p1.x-list[0].x)+sqr(p1.y-list[0].y)<
sqr(p2.x-list[0].x)+sqr(p2.y-list[0].y))
then comp:=true else comp:=false;
end;
procedure sort(l,r:integer);
var i,j:integer;
x:p;
begin
if r-l+1<=5 then begin
for j:=l+1 to r do
begin
i:=j;
while (i>1) and comp(list[i],list[i-1]) do
begin swap(list[i],list[i-1]); dec(i) end
end;
end else
begin
x:=list[l+random(r-l+1)];
i:=l;j:=r;
repeat
while comp(list[i],x) do inc(j);
while comp(x,list[j]) do dec(j);
if i<j then swap(list[i],list[j])
until i>=j;
sort(l,j);
sort(j+1,r);
end
end;
procedure init;
var i:integer;
begin
assign(f,'input.txt');
reset(f);
readln(f,n);
for i:=0 to n-1 do
begin
readln(f,list[i].x,list[i].y);
if (list[i].y<list[0].y) or
(list[i].y=list[0].y) and (list[i].x<list[0].x)
then swap(list[0],list[i]);
end ;
sort(1,n-1)
end;
procedure graham;
var i:integer;
begin
for i:=1 to 3 do s[i]:=i-1;
top:=3;
for i:=3 to n-1 do
begin
while m(list[i],list[s[top]],list[s[top-1]])>=0 do dec(top);
inc(top);
s[top]:=i;
end;
for i:=1 to top do
write('(',list[s[i]].x:7:2,',',list[s[i]].y:7:2,')');
writeln
end;
begin
init;
graham;
readln
end.