iosswiftgpsmapkitcore-location

Lines intersection - GPS coordinates


I need to detect if there is intersection between two lines. Line is a pair of CLLocationCoordinate2D. I found this https://www.movable-type.co.uk/scripts/latlong.html#intersection and tried to implement it in swift

static func intersection(
  point1: CLLocationCoordinate2D,
  bearing1: Double,
  point2: CLLocationCoordinate2D,
  bearing2: Double
) -> CLLocationCoordinate2D {
  let lat1 = Math.radians(degrees: point1.latitude)
  let lon1 = Math.radians(degrees: point1.longitude)
  let lat2 = Math.radians(degrees: point2.latitude)
  let lon2 = Math.radians(degrees: point2.longitude)

  let toSqrt = pow(sin((lat2 - lat1) / 2), 2) +
               cos(lat1) * cos(lat2) * pow(sin((lon2 - lon1) / 2), 2)
  let dist12 = 2 * asin(sqrt(toSqrt))

  let a = acos(
    (sin(lat2) - sin(lat1) * cos(dist12)) / (sin(dist12) * cos(lat1))
  )
  let b = acos(
    (sin(lat1) - sin(lat2) * cos(dist12)) / (sin(dist12) * cos(lat2))
  )

  let o12: Double
  let o21: Double

  if sin(lon2 - lon1) > 0 {
      o12 = a
      o21 = 2.0 * .pi - b
  } else {
      o12 = 2.0 * .pi - a
      o21 = b
  }

  let alpha1 = bearing1 - o12
  let alpha2 = o21 - bearing2
  let alpha3 = acos(
    -cos(alpha1) * cos(alpha2) + sin(alpha1) * sin(alpha2) * cos(dist12)
  )
  let dist13 = atan2(
    sin(dist12) * sin(alpha1) * sin(alpha2),
    cos(alpha2) + cos(alpha1) * cos(alpha3)
  )
  let lat3 = asin(
    sin(lat1) * cos(dist13) + cos(lat1) * sin(dist12) * cos(bearing1)
  )
  let deltaLon13 = atan2(
    sin(bearing1) * sin(dist12) * cos(lat1),
    cos(dist12) - sin(lat1) * sin(lat3)
  )
  let lon3 = lon1 + deltaLon13
  return CLLocationCoordinate2D(
    latitude: Math.degrees(radians: lat3),
    longitude: Math.degrees(radians: lon3)
  )
}

Unfortunately it doesn't work as expected. This is sample output: enter image description here

Is there any simple way to check if these lines intersects? I don't even need intersection point.


Solution

  • I found an error in the implementation. Should be:

    let lat3 = asin(
      sin(lat1) * cos(dist13) + cos(lat1) * sin(dist13) * cos(bearing1)
    )
    
    let deltaLon13 = atan2(
      sin(bearing1) * sin(dist13) * cos(lat1), cos(dist13) - sin(lat1) * sin(lat3)
    )