A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© qddnovo 中级黑马   /  2014-6-10 20:05  /  3308 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

看似简单却又值得注意的问题。
(从其他地方看到的源码是有问题的。)
写了很多注释了,让大家读起来方便。


  1. /// <summary>
  2.         /// 计算两条直线的交点
  3.         /// </summary>
  4.         /// <param name="lineFirstStar">L1的点1坐标</param>
  5.         /// <param name="lineFirstEnd">L1的点2坐标</param>
  6.         /// <param name="lineSecondStar">L2的点1坐标</param>
  7.         /// <param name="lineSecondEnd">L2的点2坐标</param>
  8.         /// <returns></returns>
  9.         public static PointF GetIntersection(PointF lineFirstStar, PointF lineFirstEnd, PointF lineSecondStar, PointF lineSecondEnd)
  10.         {
  11.             /*
  12.              * L1,L2都存在斜率的情况:
  13.              * 直线方程L1: ( y - y1 ) / ( y2 - y1 ) = ( x - x1 ) / ( x2 - x1 )
  14.              * => y = [ ( y2 - y1 ) / ( x2 - x1 ) ]( x - x1 ) + y1
  15.              * 令 a = ( y2 - y1 ) / ( x2 - x1 )
  16.              * 有 y = a * x - a * x1 + y1   .........1
  17.              * 直线方程L2: ( y - y3 ) / ( y4 - y3 ) = ( x - x3 ) / ( x4 - x3 )
  18.              * 令 b = ( y4 - y3 ) / ( x4 - x3 )
  19.              * 有 y = b * x - b * x3 + y3 ..........2
  20.              *
  21.              * 如果 a = b,则两直线平等,否则, 联解方程 1,2,得:
  22.              * x = ( a * x1 - b * x3 - y1 + y3 ) / ( a - b )
  23.              * y = a * x - a * x1 + y1
  24.              *
  25.              * L1存在斜率, L2平行Y轴的情况:
  26.              * x = x3
  27.              * y = a * x3 - a * x1 + y1
  28.              *
  29.              * L1 平行Y轴,L2存在斜率的情况:
  30.              * x = x1
  31.              * y = b * x - b * x3 + y3
  32.              *
  33.              * L1与L2都平行Y轴的情况:
  34.              * 如果 x1 = x3,那么L1与L2重合,否则平等
  35.              *
  36.             */
  37.             float a = 0, b = 0;
  38.             int state = 0;
  39.             if (lineFirstStar.X != lineFirstEnd.X)
  40.             {
  41.                 a = (lineFirstEnd.Y - lineFirstStar.Y) / (lineFirstEnd.X - lineFirstStar.X);
  42.                 state |= 1;
  43.             }
  44.             if (lineSecondStar.X != lineSecondEnd.X)
  45.             {
  46.                 b = (lineSecondEnd.Y - lineSecondStar.Y) / (lineSecondEnd.X - lineSecondStar.X);
  47.                 state |= 2;
  48.             }
  49.             switch (state)
  50.             {
  51.                 case 0: //L1与L2都平行Y轴
  52.                     {
  53.                         if (lineFirstStar.X == lineSecondStar.X)
  54.                         {
  55.                             //throw new Exception("两条直线互相重合,且平行于Y轴,无法计算交点。");
  56.                             return new PointF(0, 0);
  57.                         }
  58.                         else
  59.                         {
  60.                             //throw new Exception("两条直线互相平行,且平行于Y轴,无法计算交点。");
  61.                             return new PointF(0, 0);
  62.                         }
  63.                     }
  64.                 case 1: //L1存在斜率, L2平行Y轴
  65.                     {
  66.                         float x = lineSecondStar.X;
  67.                         float y = (lineFirstStar.X - x) * (-a) + lineFirstStar.Y;
  68.                         return new PointF(x, y);
  69.                     }
  70.                 case 2: //L1 平行Y轴,L2存在斜率
  71.                     {
  72.                         float x = lineFirstStar.X;
  73.                         //网上有相似代码的,这一处是错误的。你可以对比case 1 的逻辑 进行分析
  74.                             //源code:lineSecondStar * x + lineSecondStar * lineSecondStar.X + p3.Y;
  75.                         float y = (lineSecondStar.X - x) * (-b) + lineSecondStar.Y;
  76.                         return new PointF(x, y);
  77.                     }
  78.                 case 3: //L1,L2都存在斜率
  79.                     {
  80.                         if (a == b)
  81.                         {
  82.                             // throw new Exception("两条直线平行或重合,无法计算交点。");
  83.                             return new PointF(0, 0);
  84.                         }
  85.                         float x = (a * lineFirstStar.X - b * lineSecondStar.X - lineFirstStar.Y + lineSecondStar.Y) / (a - b);
  86.                         float y = a * x - a * lineFirstStar.X + lineFirstStar.Y;
  87.                         return new PointF(x, y);
  88.                     }
  89.             }
  90.             // throw new Exception("不可能发生的情况");
  91.             return new PointF(0, 0);
  92.         }
复制代码

点评

典型的数学问题  发表于 2014-6-12 14:51

3 个回复

倒序浏览
楼主这是要自己写碰撞检查的趋势啊
回复 使用道具 举报
yllogininbh 发表于 2014-6-11 21:07
楼主这是要自己写碰撞检查的趋势啊

相互学习啦,加油啦
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马