這題主要是給正方形對角線兩個點求另外兩個點:不用旋轉什麼的,可以由點之間的關係推得。比較好推,具體見代碼。
剩下的思路比較簡單,輸入輸出有點麻煩,尤其是 A and C 和 A, B, and C 這種的區別。。。
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <queue>
#include <map>
#include <vector>
#include <set>
#include <string>
#include <math.h>
#include <cstdio>
#include <cstring>
#include <cctype>
using namespace std;
const double eps = 1e-8;
int sgn(double x)
{
if (fabs(x) < eps) return 0;
if (x < 0) return -1;
else return 1;
}
struct Point
{
double x,y;
Point(){}
Point(double _x,double _y)
{
x = _x;y = _y;
}
//向量
Point operator -(const Point &b)const
{
return Point(x - b.x,y - b.y);
}
//叉積
double operator ^(const Point &b)const
{
return x*b.y - y*b.x;
}
//點積
double operator *(const Point &b)const
{
return x*b.x + y*b.y;
}
void input()
{
scanf("%lf%lf",&x,&y);
}
};
struct Line
{
Point s,e;
Line(){}
Line(Point _s,Point _e)
{
s = _s;e = _e;
}
//兩直線相交求交點
//第一個值爲0表示直線重合,爲1表示平行,爲0表示相交,爲2是相交
//只有第一個值爲2時,交點纔有意義
pair<int,Point> operator &(const Line &b)const
{
Point res = s;
if (sgn((s-e)^(b.s-b.e)) == 0)
{
if(sgn((s-b.e)^(b.s-b.e)) == 0)
return make_pair(0,res);//重合
else return make_pair(1,res);//平行
}
double t = ((s-b.s)^(b.s-b.e))/((s-e)^(b.s-b.e));
res.x += (e.x-s.x)*t;
res.y += (e.y-s.y)*t;
return make_pair(2,res);
}
};
bool inter(Line l1,Line l2)//判斷線段相交
{
return
max(l1.s.x,l1.e.x) >= min(l2.s.x,l2.e.x) &&
max(l2.s.x,l2.e.x) >= min(l1.s.x,l1.e.x) &&
max(l1.s.y,l1.e.y) >= min(l2.s.y,l2.e.y) &&
max(l2.s.y,l2.e.y) >= min(l1.s.y,l1.e.y) &&
sgn((l2.s-l1.e)^(l1.s-l1.e))*sgn((l2.e-l1.e)^(l1.s-l1.e)) <= 0 &&
sgn((l1.s-l2.e)^(l2.s-l2.e))*sgn((l1.e-l2.e)^(l2.s-l2.e)) <= 0;
}
typedef struct Shape {
string name, type;
int pnum, snum;
Point pts[27];
Line segs[27];
}Shape;
Shape shape[32];
Point getp()
{
Point ret;
string str;
cin >> str;
ret.x = ret.y = 0;
int pos = 0;
double sign = 1;
if(str[pos+1] == '-') {
sign = -1;
pos++;
}
while (isdigit(str[++pos]))
ret.x = ret.x * 10 + double(str[pos] - '0');
ret.x *= sign;
sign = 1;
if(str[pos+1] == '-') {
sign = -1;
pos++;
}
while (isdigit(str[++pos]))
ret.y = ret.y * 10 + double(str[pos] - '0');
ret.y *= sign;
return ret;
}
bool cmp(Shape a, Shape b)
{
return a.name < b.name;
}
int main()
{
int scnt = 0;
string str1, str2;
while (cin >> str1) {
Shape & curs = shape[scnt];
if (str1 == "-") {
sort(shape, shape+scnt, cmp);
for (int i = 0; i < scnt; i++) {
cout << shape[i].name;
int ccnt = 0;
string buf[100];
for (int j = 0; j < scnt; j++) {
if (i == j) continue;
bool cro = false;
for (int i0 = 0; !cro && i0 < shape[i].snum; i0++) {
for (int j0 = 0; j0 < shape[j].snum; j0++) {
if (inter(shape[i].segs[i0], shape[j].segs[j0])) {
cro = true;
break;
}
}
}
if (cro)
buf[ccnt++] = shape[j].name;
}
if (ccnt == 0)
cout << " has no intersections" << endl;
else {
cout << " intersects with ";
for (int j = 0; j < ccnt; j++) {
if (j == 0)
cout << buf[j];
else if (j == ccnt - 1) {
if(ccnt != 2) cout << ",";
cout << " and " << buf[j] << endl;
}
else
cout << ", " << buf[j];
}
if (ccnt == 1)
cout << endl;
}
}
scnt = 0;
cout << endl;
continue;
} else if (str1 == ".")
break;
else
cin >> str2;
curs.name = str1;
curs.type = str2;
if (curs.type == "square") {
Point p[4];
p[0] = getp(), p[2] = getp();
curs.pnum = curs.snum = 4;
double x0 = p[0].x, y0 = p[0].y;
double x2 = p[2].x, y2 = p[2].y;
double a = x0 + x2, b = y2 - y0, c = y0 +y2, d = x0 - x2;
p[1].x = (a + b) / 2.0, p[1].y = (c + d) / 2.0;
p[3].x = (a - b) / 2.0, p[3].y = (c - d) / 2.0;
for (int i = 0; i < 4; i++) {
curs.pts[i] = p[i];
curs.segs[i].s = p[i];
curs.segs[i].e = p[(i+1) % 4];
}
} else if (curs.type == "rectangle") {
Point p[4];
for(int i = 0; i < 3; i++) p[i] = getp();
p[3].x = p[2].x + p[0].x - p[1].x;
p[3].y = p[2].y + p[0].y - p[1].y;
curs.pnum = curs.snum = 4;
for (int i = 0; i < 4; i++) {
curs.pts[i] = p[i];
curs.segs[i].s = p[i];
curs.segs[i].e = p[(i+1) % 4];
}
} else if (curs.type == "line") {
curs.pnum = 2;
curs.snum = 1;
curs.segs[0].s = curs.pts[0] = getp();
curs.segs[0].e = curs.pts[1] = getp();
} else if (curs.type == "triangle") {
curs.pnum = curs.snum = 3;
for (int i = 0; i < 3; i++)
curs.segs[i].s = curs.segs[(i+2) % 3].e = curs.pts[i] = getp();
} else if (curs.type == "polygon") {
cin >> curs.pnum;
curs.snum = curs.pnum;
for (int i = 0; i < curs.pnum; i++)
curs.segs[i].s = curs.segs[(i+curs.pnum-1) % curs.pnum].e = curs.pts[i] = getp();
}
scnt++;
}
return 0;
}