zoukankan      html  css  js  c++  java
  • 一般方程与参数方程求直线交点

    一、             一个例子:


    如上图,有两条直线,设L1L2L1上有两点(0, 0)(10,10)L2上有两点(0,10)(10,0),它们的交点是(5,5)。求解交点有两种效率较高的常用方法,一般方程法与参数方程法,以下将分别描述其原理及实现。

    二、             一般方程法:

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

    源代码:


     1 #include <iostream>
     2 using namespace std;
     3 
     4 typedef struct
     5 {
     6     int x, y;
     7 } Point;
     8 int main()
     9 {
    10     //一般方程法
    11     Point line1[2], line2[2];
    12     int a[2], b[2], c[2], x, y, D;
    13     cout << "Frist Line(x0 y0 x1 y1):";
    14     cin >> line1[0].x >> line1[0].y >> line1[1].x >> line1[1].y;
    15     cout << "Second Line(x0 y0 x1 y1):";
    16     cin >> line2[0].x >> line2[0].y >> line2[1].x >> line2[1].y;
    17     
    18     a[0= line1[0].y - line1[1].y;b[0= line1[1].x - line1[0].x;
    19     c[0= line1[0].x * line1[1].y - line1[1].x * line1[0].y;
    20     a[1= line2[0].y - line2[1].y;b[1= line2[1].x - line2[0].x;
    21     c[1= line2[0].x * line2[1].y - line2[1].x * line2[0].y;
    22     D = a[0* b[1- a[1* b[0];
    23     if (D != 0)
    24     {
    25         x = (b[0* c[1- b[1* c[0]) / D; y = (a[1* c[0- a[0* c[1]) / D;    
    26         cout << "一般方程求解的交点:" << x << "," << y << endl;
    27     }
    28     else
    29     {
    30         cout << "两直线重合" << endl;
    31     }
    32     return 0;
    33 }
    34 


    三、             参数方程法:

    设直线上的两个点为A0(x0, y0), B0(x1, y1),那么线段可用向量

     =  –=(x1 – x0, y1 – y0)

    表示,的方向即为直线上的方向,那么直线上的任意点便可表示为

    s0(t0) = +  t0 *

    同理,另一条直线(A1(x2, y2), B1(x3, y3)为其上两个点)可类似表示为

    s1(t1) =  +  t1 *

    因此,满足两条直线的交点必满足以下条件:

    + t0 * =  + t1 *

    可求出

    t0 = (x0(y3 – y2) + x2(y0 – y3) + x3(y2 – y0))/D

    t1 = -(x0(y2 – y1) + x1(y0 – y2) + x2(y1 – y0))/D

    D = x0(y3 – y2) + x1(y2 – y3) + x3(y1 – y0) + x2(y0 – y1),(D0时,表示两直线重合)

    则交点为:

           x = x0 + t0 * (x1 – x0); y = y0 + t0 * (y1 – y0);

          

           x = x2 + t1 * (x3 – x2); y = y2 + t1 * (y3 – y2);

    如果将t0,t1限定在[0,1]内,则变为求线段的求点

    源代码:


     1 #include <iostream>
     2 using namespace std;
     3 
     4 typedef struct
     5 {
     6     int x, y;
     7 } Point;
     8 int main()
     9 {
    10     //参数方程法
    11     Point pt[4];
    12     int t1, t2, dx, dy, D, x, y;
    13     cout << "Frist Line(x0 y0 x1 y1):";
    14     cin >> pt[0].x >> pt[0].y >> pt[1].x >> pt[1].y;
    15     cout << "Second Line(x0 y0 x1 y1):";
    16     cin >> pt[2].x >> pt[2].y >> pt[3].x >> pt[3].y;    
    17     t1 = pt[0].x * (pt[3].y - pt[2].y) + pt[2].x * (pt[0].y - pt[3].y) + pt[3].x * (pt[2].y - pt[0].y);
    18     t2 = - (pt[0].x * (pt[2].y - pt[1].y) + pt[1].x * (pt[0].y - pt[2].y) + pt[2].x * (pt[1].y - pt[0].y));
    19     D = pt[0].x * (pt[3].y - pt[2].y) + pt[1].x * (pt[2].y - pt[3].y) + pt[3].x * (pt[1].y - pt[0].y) + pt[2].x * (pt[0].y - pt[1].y);
    20     if (D != 0)
    21     {
    22         dx = pt[1].x - pt[0].x; dy = pt[1].y - pt[0].y;
    23         x = pt[0].x + t1 * dx / D; y = pt[0].y + t1 * dy / D;
    24         cout <<"参数法求交点:" << x << "," << y <<  endl;
    25     }
    26     else
    27     {
    28         cout << "两直线重合" << endl;
    29     }
    30     return 0;
    31 }
    32 


    四、             测试结果:


  • 相关阅读:
    网页连接无法打开可运行
    SET XACT_ABORT
    用Windows Live Writer写CSDN博客的步骤
    ATO,PTO
    什么是贸易顺差?
    ATO/MTO类机械制造业特点以及ERP需求分析(二)
    如何在早期版本的 Office 中打开并保存 Word 2007、Excel 2007 和 PowerPoint 2007 文件
    Alpha和Beta测试简介
    IIS6.0下 Asp网页访问出现500的问题
    合格的程序员
  • 原文地址:https://www.cnblogs.com/pheye/p/1817337.html
Copyright © 2011-2022 走看看