对于两条直线上的点, M(ax1,ay1) N (ax2,ay2) P(bx1,by1) Q(bx2,by2)
若两直线相交,则任意一条直线的两个端点,都在另一条直线的两侧。
我们可以使用向量外积 或者 线性规划 来判断。
此处使用外积。
MN 与 MP 的外积 MNP = (ax1 - ax2)*(ay1 - by1) - (ay1 - ay2)*(ax1 - bx1)
MN 与 MQ 的外积 MNQ = (ax1 - ax2)*(ay1 - by2) - (ay1 - ay2)*(ax1 - bx2)
若MNP 和 MNQ 异号,则点在线的两侧。
MNP 和 MNQ 的积 为0,则有点在线上,因此也算作有交点。
#include <stdio.h>
#include <stdlib.h>
struct node
{
double x,y;
}s1[105],s2[105];
int ans;
void wtf(int a,int b)
{
double abc = (s1[a].x - s2[a].x)*(s1[a].y - s1[b].y) - (s1[a].y - s2[a].y)*(s1[a].x - s1[b].x);
double abd = (s1[a].x - s2[a].x)*(s1[a].y - s2[b].y) - (s1[a].y - s2[a].y)*(s1[a].x - s2[b].x);
double cda = (s1[b].x - s2[b].x)*(s1[b].y - s2[a].y) - (s1[b].y - s2[b].y)*(s1[b].x - s2[a].x);
double cdb = (s1[b].x - s2[b].x)*(s1[b].y - s1[a].y) - (s1[b].y - s2[b].y)*(s1[b].x - s1[a].x);
if((abc * abd) <= 0 && (cda * cdb) <= 0) ans++;
}
int main()
{
// freopen("t.txt","r",stdin);
int n,i,j;
while(~scanf("%d",&n) && n)
{
ans = 0;
for(i = 0; i < n; i++)
{
scanf("%lf%lf%lf%lf",&s1[i].x,&s1[i].y,&s2[i].x,&s2[i].y);
}
for(i = 1; i < n; i++)
{
for(j = 0; j < i; j++)
{
wtf(i,j);
}
}
printf("%d\n",ans);
}
return 0;
}