用scala改写C语言代码判断点是否在多边形内部

判断点是否在多边形内部有多种算法,这里主要参考了 http://blog.csdn.net/hgl868/article/details/7947272 用C语言编写的射线法

然后将C的算法改成了scala编写,用于实际工作需要_(:зゝ∠)_,主要是地图区域数据处理用的,效果还不错

点的类
class myPoint {
  var x: Double = 0
  var y: Double = 0
}

线的类
class LineSegment {
  var pt1: myPoint = new myPoint()
  var pt2: myPoint = new myPoint()
}

工具类
import java.util

/**
  * Created by luojie on 2017/1/26.
  */
class polygonServer {
  val INFINITY: Double = 1e10
  val ESP: Double = 1e-5

  // 判断点在多边形内
  def inPolygon(polygon: util.ArrayList[myPoint], point: myPoint): Boolean = {
      //顶点数
      val n = polygon.size()
      //射线与多边形交点数
      var count = 0
      //定义射线
      val line: LineSegment = new LineSegment
      line.pt1 = point
      line.pt2.y = point.y
      line.pt2.x = -INFINITY
      
      for (i <- 0 to n - 1) {
        // 得到多边形的一条边
        val side: LineSegment = new LineSegment()
        side.pt1 = polygon.get(i)
        side.pt2 = polygon.get((i + 1) % n)
        if (isOnline(point, side)) {
          return true
        }
        // 如果side平行x轴则不作考虑
        if (dabs(side.pt1.y - side.pt2.y) < ESP) {
        }
	//
        if (isOnline(side.pt1, line)) {
          if (side.pt1.y > side.pt2.y) count += 1
        } else if (isOnline(side.pt2, line)) {
          if (side.pt2.y > side.pt1.y) count += 1
        } else if (intersect(line, side)) {
          count += 1
        }
      }
      if (count % 2 == 1) {
        return true
      } else {
	return flase
      }

  }

  // 计算叉乘 |P0P1| × |P0P2|
  def multiply(p1: myPoint, p2: myPoint, p0: myPoint): Double =
  (p1.x - p0.x) * (p2.y - p0.y) - (p2.x - p0.x) * (p1.y - p0.y)


  // 判断线段是否包含点point
  def isOnline(point: myPoint, line: LineSegment): Boolean =
  (dabs(multiply(line.pt1, line.pt2, point)) < ESP) &&
    ((point.x - line.pt1.x) * (point.x - line.pt2.x) <= 0) &&
    ((point.y - line.pt1.y) * (point.y - line.pt2.y) <= 0)


  // 判断线段相交
  def intersect(L1: LineSegment, L2: LineSegment): Boolean =
  (maxBy(L1.pt1.x, L1.pt2.x) >= minBy(L2.pt1.x, L2.pt2.x)) &&
    (maxBy(L2.pt1.x, L2.pt2.x) >= minBy(L1.pt1.x, L1.pt2.x)) &&
    (maxBy(L1.pt1.y, L1.pt2.y) >= minBy(L2.pt1.y, L2.pt2.y)) &&
    (maxBy(L2.pt1.y, L2.pt2.y) >= minBy(L1.pt1.y, L1.pt2.y)) &&
    (multiply(L2.pt1, L1.pt2, L1.pt1) * multiply(L1.pt2, L2.pt2, L1.pt1) >= 0) &&
    (multiply(L1.pt1, L2.pt2, L2.pt1) * multiply(L2.pt2, L1.pt2, L2.pt1) >= 0)
	
  //绝对值
  def dabs(x: Double): Double = if (x > 0) x else 0 - x
  //取较大值
  def maxBy(x: Double, y: Double): Double = if (x > y) x else y
  //取较小值
  def minBy(x: Double, y: Double): Double = if (x < y) x else y

}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值