一般方程法:
直线的一般方程为F(x) = ax + by + c = 0。既然我们已经知道直线的两个点,假设为(x0,y0), (x1, y1),那么可以得到a = y0 – y1, b = x1 – x0, c = x0y1 – x1y0。
因此我们可以将两条直线分别表示为
F0(x) = a0*x + b0*y + c0 = 0, F1(x) = a1*x + b1*y + c1 = 0
那么两条直线的交点应该满足
a0*x + b0*y +c0 = a1*x + b1*y + c1
由此可推出
x = (b0*c1 – b1*c0)/D
y = (a1*c0 – a0*c1)/D
D = a0*b1 – a1*b0, (D为0时,表示两直线重合)
二者实际上就是连立方程组F0(x) = a0*x + b0*y + c0 = 0, F1(x) = a1*x + b1*y + c1 = 0的叉积应用
i j k
a0 b0 c0
a1 b1 c1
- #include <iostream>
- #include <string>
-
- using namespace std;
-
- struct Point
- {
- double x;
- double y;
- };
-
- struct Line
- {
- Point p1,p2;
- double a,b,c;
- };
-
- void GetLinePara(Line &l)
- {
- l.a=l.p1.y-l.p2.y;
- l.b=l.p2.x-l.p1.x;
- l.c=l.p1.x*l.p2.y-l.p1.y*l.p2.x;
- }
-
- Point getCrossPoint(Line &l1,Line &l2)
- {
- GetLinePara(l1);
- GetLinePara(l2);
- double D=l1.a*l2.b-l2.a*l1.b;
- Point p;
- p.x=(l1.b*l2.c-l2.b*l1.c)/D;
- p.y=(l1.c*l2.a-l2.c*l1.a)/D;
- return p;
- }
- int main()
- {
- Line L1,L2;
- while(true)
- {
- cout<<"Line1:\n"<<"Point1.x: ";
- cin>>L1.p1.x;
- cout<<"Point1.y: ";
- cin>>L1.p1.y;
- cout<<"Line1:\n"<<"Point2.x: ";
- cin>>L1.p2.x;
- cout<<"Point2.y: ";
- cin>>L1.p2.y;
- cout<<"Line2:\n"<<"Point1.x: ";
- cin>>L2.p1.x;
- cout<<"Point1.y: ";
- cin>>L2.p1.y;
- cout<<"Line2:\n"<<"Point2.x: ";
- cin>>L2.p2.x;
- cout<<"Point2.y: ";
- cin>>L2.p2.y;
- cout<<endl;
-
- Point PointCross=getCrossPoint(L1,L2);
- cout<<"CrossPoint.x:"<<PointCross.x<<endl;
- cout<<"CrossPoint.y:"<<PointCross.y<<endl;
- cout<<endl;
- }
- }
ZOJ Problem Set - 1683
题目大意:
在1*1的正方形格子上给出每边的两个点,按顺序连接对边的点,求这样形成的一系列四边形中最大的面积。
![](http://acm.zju.edu.cn/onlinejudge/showImage.do?name=0000%2F1683%2F1683-2.gif)
思路:
1. 求交点
见函数GetCrossPoint (http://blog.csdn.NET/abcjennifer/article/details/7584628)
2. 求面积
四边形面积可由两个三角形面积相加而得,这里使用叉积,因为三角形的两个向量边叉乘的结果为其所形成的平行四边形面积,所以三角形面积为1/2×向量边1 x 向量边2
见函数GetArea()
Code:
- #include"iostream"
- #include"stdio.h"
- #include"math.h"
- using namespace std;
-
- #define N 40
- int n;
-
- struct Point {
- double x;
- double y;
- } pset[N + 1][N + 1];
-
- struct Line {
- void L(Point pp1, Point pp2) {
- p1 = pp1;
- p2 = pp2;
- }
- Point p1, p2;
- double a, b, c;
- } lineset[N][N];
-
- void GetLinePara(Line *l) {
- l->a = l->p1.y - l->p2.y;
- l->b = l->p2.x - l->p1.x;
- l->c = l->p1.x * l->p2.y - l->p2.x * l->p1.y;
- }
-
- Point GetCrossPoint(Line *l1, Line *l2) {
- GetLinePara(l1);
- GetLinePara(l2);
- double D = l1->a * l2->b - l2->a * l1->b;
- Point p;
- p.x = (l1->b * l2->c - l2->b * l1->c) / D;
- p.y = (l1->c * l2->a - l2->c * l1->a) / D;
- return p;
- }
-
- double Xmult(Point a, Point b, Point c)
- {
- return (c.x - a.x) * (c.y - b.y) - (c.y - a.y) * (c.x - b.x);
- }
-
- double GetArea(int i, int j) {
- double area1 = Xmult(pset[i][j], pset[i + 1][j], pset[i + 1][j + 1]) / 2;
- double area2 = Xmult(pset[i][j], pset[i][j + 1], pset[i + 1][j + 1]) / 2;
- return fabs(area1) + fabs(area2);
- }
-
- void Init_Points() {
- int i;
- for (i = 1; i <= n; i++)
- scanf("%lf", &pset[i][0].x), pset[i][0].y = 0;
- for (i = 1; i <= n; i++)
- scanf("%lf", &pset[i][n + 1].x), pset[i][n + 1].y = 1;
- for (i = 1; i <= n; i++)
- scanf("%lf", &pset[0][i].y), pset[0][i].x = 0;
- for (i = 1; i <= n; i++)
- scanf("%lf", &pset[n + 1][i].y), pset[n + 1][i].x = 1;
-
- pset[0][0].x = pset[0][0].y = 0;
- pset[n + 1][0].x = 1, pset[n + 1][0].y = 0;
- pset[0][n + 1].x = 0, pset[0][n + 1].y = 1;
- pset[n + 1][n + 1].x = pset[n + 1][n + 1].y = 1;
- }
-
- void Init_Lines() {
- int i, j;
- Line l1, l2;
- for (i = 1; i <= n; i++) {
- for (j = 1; j <= n; j++) {
- l1.L(pset[i][0], pset[i][n + 1]);
- l2.L(pset[0][j], pset[n + 1][j]);
- pset[i][j] = GetCrossPoint(&l1, &l2);
- }
- }
- }
-
- int main() {
- int i, j;
- while (cin >> n&&n) {
- Init_Points();
- Init_Lines();
- double maxarea = 0;
- double area;
- for (i = 0; i < n + 1; i++)
- for (j = 0; j < n + 1; j++) {
- area = GetArea(i, j);
- maxarea = area > maxarea ? area : maxarea;
- }
- printf("%lf\n", maxarea);
- }
- }