How to resolve the algorithm Convex hull step by step in the Haskell programming language

Published on 7 June 2024 03:52 AM

How to resolve the algorithm Convex hull step by step in the Haskell programming language

Table of Contents

Problem Statement

Find the points which form a convex hull from a set of arbitrary two dimensional points. For example, given the points (16,3), (12,17), (0,6), (-4,-6), (16,6), (16,-7), (16,-3), (17,-4), (5,19), (19,-8), (3,16), (12,13), (3,-4), (17,5), (-3,15), (-3,-9), (0,11), (-9,-3), (-4,-2) and (12,10) the convex hull would be (-9,-3), (-3,-9), (19,-8), (17,5), (12,17), (5,19) and (-3,15).

Let's start with the solution:

Step by Step solution about How to resolve the algorithm Convex hull step by step in the Haskell programming language

This Haskell code implements the Graham scan algorithm to compute the convex hull of a set of 2D points.

The algorithm starts by finding the point with the smallest y-coordinate, which is the lowest point in the set. This point is used as the origin for the algorithm.

The remaining points are sorted by their angle with respect to the origin, using the compareFrom function. This function takes three points: the origin, a point to be sorted, and another point that is used as a reference.

It returns an ordering that indicates whether the point to be sorted is to the left, right, or on the same line as the reference point.

The sorted list of points is then grouped by their angle with respect to the origin, using the groupBy function. This function takes a function that compares two elements and returns a group for each element that compares equal to the first element.

The outmost variable is then set to the group with the largest distance from the origin, using the maximumBy function. This function takes a function that compares two elements and returns the element with the largest value.

The dropConcavities function is then used to remove any points that are not on the convex hull. This function takes two lists of points: the points that are currently on the convex hull and the points that are not.

It returns a new list of points that are on the convex hull, by removing any points that are not on the convex hull and that are not colinear with the two points on either side of them.

The main function reads a list of points from the standard input and prints the convex hull of the points to the standard output.

Source code in the haskell programming language

import Data.List (sortBy, groupBy, maximumBy)
import Data.Ord (comparing)

(x, y) = ((!! 0), (!! 1))

compareFrom
  :: (Num a, Ord a)
  => [a] -> [a] -> [a] -> Ordering
compareFrom o l r =
  compare ((x l - x o) * (y r - y o)) ((y l - y o) * (x r - x o))

distanceFrom
  :: Floating a
  => [a] -> [a] -> a
distanceFrom from to = ((x to - x from) ** 2 + (y to - y from) ** 2) ** (1 / 2)

convexHull
  :: (Floating a, Ord a)
  => [[a]] -> [[a]]
convexHull points =
  let o = minimum points
      presorted = sortBy (compareFrom o) (filter (/= o) points)
      collinears = groupBy (((EQ ==) .) . compareFrom o) presorted
      outmost = maximumBy (comparing (distanceFrom o)) <$> collinears
  in dropConcavities [o] outmost

dropConcavities
  :: (Num a, Ord a)
  => [[a]] -> [[a]] -> [[a]]
dropConcavities (left:lefter) (right:righter:rightest) =
  case compareFrom left right righter of
    LT -> dropConcavities (right : left : lefter) (righter : rightest)
    EQ -> dropConcavities (left : lefter) (righter : rightest)
    GT -> dropConcavities lefter (left : righter : rightest)
dropConcavities output lastInput = lastInput ++ output

main :: IO ()
main =
  mapM_ print $
  convexHull
    [ [16, 3]
    , [12, 17]
    , [0, 6]
    , [-4, -6]
    , [16, 6]
    , [16, -7]
    , [16, -3]
    , [17, -4]
    , [5, 19]
    , [19, -8]
    , [3, 16]
    , [12, 13]
    , [3, -4]
    , [17, 5]
    , [-3, 15]
    , [-3, -9]
    , [0, 11]
    , [-9, -3]
    , [-4, -2]
    , [12, 10]
    ]


  

You may also check:How to resolve the algorithm Floyd's triangle step by step in the Raku programming language
You may also check:How to resolve the algorithm Lah numbers step by step in the C programming language
You may also check:How to resolve the algorithm Bitmap/Bresenham's line algorithm step by step in the C programming language
You may also check:How to resolve the algorithm Continued fraction/Arithmetic/G(matrix ng, continued fraction n1, continued fraction n2) step by step in the Go programming language
You may also check:How to resolve the algorithm Selectively replace multiple instances of a character within a string step by step in the RPL programming language