第一种解法:将三角形化为梯形面积减去两个三角形面积
无论三角形的顶点位置如何,△PMN总可以用一个直角梯形(或矩形)和两个直角三角形面积的和差来表示
而在直角坐标系中,已知直角梯形和直角三角形的顶点的坐标,其面积是比较好求的。
下面以一种情形来说明这个方法,其它情形方法一样,表达式也一样(表达式最好加上绝对值,确保是正值)
如图情形(P在上方,M在左下,N在右下),过P作X轴的平行线L,作MA⊥L,NB⊥L(设P在A、B之间)
则A、B的坐标是A(c,b),B(e,b)
所以PA=a-c,PB=e-a,AM=b-d,BN=b-f,AB=e-c
所以S△PMN=S梯形AMNB-S△PAM-S△PBN
=(b-d+b-f)(e-c)/2-(b-d)(a-c)/2-(b-f)(e-a)/2
=(ad+be+cf-af-bc-de)/2
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=105;
int x[maxn],y[maxn];
double area(int a,int b,int c,int d,int e,int f)
{
return (a*d+c*f+b*e-e*d-c*b-a*f)/2.0;
}
int main()
{
int n;
while(cin>>n){
if(n==0){
break;
}else{
for(int i=0;i<n;i++){
cin>>x[i]>>y[i];
}
double res=0;
for(int i=1;i<n-1;i++){
res+=area(x[0],y[0],x[i],y[i],x[i+1],y[i+1]);
}
printf("%.1lf\n",res);
}
}
return 0;
}
第二种:使用叉乘
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=105;
struct point{
int x,y;
};
point points[maxn];
double cross(point a,point b)
{
return a.x*b.y*1.0-a.y*b.x*1.0;
}
int main()
{
int n;
while(cin>>n){
if(n==0){
break;
}else{
for(int i=0;i<n;i++){
cin>>points[i].x>>points[i].y;
}
double sum=cross(points[n-1],points[0]);
for(int i=1;i<n;i++){
sum+=cross(points[i-1],points[i]);
}
printf("%.1f\n",sum*0.5);
}
}
return 0;
}