算法之美——求两直线交点(三维叉积)——求四边形面积(二维叉积)

    xiaoxiao2021-03-25  76

    一般方程法:

    直线的一般方程为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 (D0时,表示两直线重合)

    二者实际上就是连立方程组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

    [cpp]  view plain  copy  print ? #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的正方形格子上给出每边的两个点,按顺序连接对边的点,求这样形成的一系列四边形中最大的面积。

    思路:

    1. 求交点

          见函数GetCrossPoint (http://blog.csdn.NET/abcjennifer/article/details/7584628)

    2. 求面积

          四边形面积可由两个三角形面积相加而得,这里使用叉积,因为三角形的两个向量边叉乘的结果为其所形成的平行四边形面积,所以三角形面积为1/2×向量边1 x 向量边2

          见函数GetArea()

    Code:

    [cpp]  view plain  copy  print ? #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)//get vector ac and bc 计算两个二维向量叉积,两条边界向量   {       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);       }   }  
    转载请注明原文地址: https://ju.6miu.com/read-35822.html

    最新回复(0)