The centroid of a list of points

centroid formula
centroid of points
centroid calculator
centroid formula for all shapes
centroid of points python
centroid formula integral
centroid formula calculus
how to find centroid

New to Haskell

The problem is

-- The centroid of a list of points is a point whose x (and y) coordinates are
-- the means of the x (and y) coordinates of the points in the list.
--
-- You may assume the list contains at least one point.
--
-- > centroid [Pt 1 1, Pt 2 2]
-- Pt 1.5 1.5
-- > centroid [Pt (-1.5) 0, Pt 3 2, Pt 0 1]
-- Pt 0.5 1.0

Try to code like this

data Point = Pt Double Double deriving (Show, Eq)

centroid :: [Point] -> Point

pointX :: Point -> Double
pointX (Pt x y) = x
pointY :: Point -> Double
pointY (Pt x y) = y

pointsX :: [Point] -> [Double]
pointsX xs = map pointX xs
pointsY :: [Point] -> [Double]
pointsY xs = map pointY xs

average :: [Double] -> Double
average xs = (sum xs) `div` (genericLength xs)

centroid cenpoint = (Pt average(pointsX cenpoint) average(pointsY cenpoint))

And I got

Project1.hs:35:22: error:
    • Couldn't match expected type ‘([Double] -> Double)
                                    -> [Double] -> Point’
                  with actual type ‘Point’
    • The function ‘Pt’ is applied to four arguments,
      but its type ‘Double -> Double -> Point’ has only two
      In the expression:
        (Pt average (pointsX cenpoint) average (pointsY cenpoint))
      In an equation for ‘centroid’:
          centroid cenpoint
            = (Pt average (pointsX cenpoint) average (pointsY cenpoint))
   |
35 | centroid cenpoint = (Pt average(pointsX cenpoint) average(pointsY cenpoint))
   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Project1.hs:35:25: error:
    • Couldn't match expected type ‘Double’
                  with actual type ‘[Double] -> Double’
    • Probable cause: ‘average’ is applied to too few arguments
      In the first argument of ‘Pt’, namely ‘average’
      In the expression:
        (Pt average (pointsX cenpoint) average (pointsY cenpoint))
      In an equation for ‘centroid’:
          centroid cenpoint
            = (Pt average (pointsX cenpoint) average (pointsY cenpoint))
   |
35 | centroid cenpoint = (Pt average(pointsX cenpoint) average(pointsY cenpoint))
   |                         ^^^^^^^

Project1.hs:35:33: error:
    • Couldn't match expected type ‘Double’ with actual type ‘[Double]’
    • In the second argument of ‘Pt’, namely ‘(pointsX cenpoint)’
      In the expression:
        (Pt average (pointsX cenpoint) average (pointsY cenpoint))
      In an equation for ‘centroid’:
          centroid cenpoint
            = (Pt average (pointsX cenpoint) average (pointsY cenpoint))
   |
35 | centroid cenpoint = (Pt average(pointsX cenpoint) average(pointsY cenpoint))
   |

You were doing pretty well - note how the compilation errors all point to your final line (the definition of centroid). And they're all due to incorrect bracketing. This is what it should be instead:

centroid cenpoint = Pt (average (pointsX cenpoint)) (average (pointsY cenpoint))

That is, the x co-ordinate of the resulting Pt value is the average of the x co-ordinates of the corresponding points (pointsX cenpoint is the list of x-coordinates, so average (pointsX cenpoint) is their average), and similarly for the y co-ordinate.

Comparing to your incorrect version (which I have tidied up a little without changing how it is interpreted by the compiler):

Pt average (pointsX cenpoint) average (pointsY cenpoint)

This means you apply the Pt function to 4 arguments: average, pointsX cenpoint, average again, and pointsY cenpoint. This simply doesn't work because the Pt function only takes 2 arguments.

Centroid Formula, centroid of a triangle are found by averaging the x- and y-coordinates of the vertices. This method will also find the centroid (center of mass) of any set of points  In the diagram at the top of the page, Drag the points A, B or C around and notice how the centroid moves and the coordinates are calculated. Try points that are negative in x and y. You can drag the origin point to move the axes. Click "hide details". Drag the triangle to some random new shape.

The main problem here is that you call the functions, like you would do in a language like Java, C++, or Python.

You need to wrap average into parenthesis, like:

centroid cenpoint = Pt (average (pointsX cenpoint)) (average (pointsY cenpoint))

As @dfeuer says, the outer parenthesis are not necessary here.

Furthermore you probably want to use (/) here over div, since you are working with Doubles, whereas div works on Integral types:

average :: [Double] -> Double
average xs = sum xs / genericLength xs

but like @leftroundabout says, we can better use length, and then use fromIntegral:

average :: [Double] -> Double
average xs = sum xs / fromIntegral (length xs)

Centroid, How do you find the centroid of a set of points? It is the point which corresponds to the mean position of all the points in a figure. The centroid is the term for 2-dimensional shapes. The center of mass is the term for 3-dimensional shapes. For instance, the centroid of a circle and a rectangle is at the middle. The centroid of a right triangle is 1/3 from the bottom and the right angle.

Not really an answer to the question, but – this is the preferred way of doing it:

{-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}

import Data.VectorSpace
import GHC.Generics

data Point = Pt Double Double
   deriving (Eq, Show, Generic, AdditiveGroup, VectorSpace)

average :: (VectorSpace v, Fractional (Scalar v)) => [v] -> v
average ps = sumV ps ^/ fromIntegral (length xs)

Then you can directly do

> average [Pt (-1.5) 0, Pt 3 2, Pt 0 1]
Pt 0.5 1.0

I.e. centroid ≡ average.

How to Find the Centroid of a Triangle, , follow these steps: Step 1: Identify the coordinates of each vertex. Step 2: Add all the x values from the three vertices coordinates and divide by 3. Step 3: Add all the y values from the three vertices coordinates and divide by 3. Each centroid defines one of the clusters. centroids_to_list() ``` Similarly, you can restore a Python dict of digest values with `update_from_dict()`. e Y predicts the centroid closest to the point X Apr 23, 2014 · But for about 3% (29 of 1,038) of my polygons, the coords returned by getting centroid.

What is the formula of a centroid?, . Centroid of points, A, B and C is (x1+x2+x3)/3, (y1+y2+y3)/3. The centroid of the triangle is given by ( a + b + c3, a + b + c3 ) Given that the centroid of the triangle is origin. ( a + b + c3, a + b + c3 ) = (0,0) a + b + c = 0 Now consider the identity, a3 + b3 + c3 - 3abc = (a + b + c)(a2 + b2 + c2 - ab - bc - ca) Since a + b + c = 0 we get a3 + b3 + c3 - 3abc = 0 a3 + b3 + c3 = 3abc a3 + b3 + c3abc = 3

Finding centroid of cluster of points using R, at which a cutout of the shape could be perfectly balanced on the tip of a pin. +1 Great solution. It extends to centroids on the spheroid, too (which is essential for avoiding projection-related distortions when the points are spread over a large portion of the globe): first convert (lat, lon) to 3D (x,y,z) (geocentric) coordinates, average them, then convert the result back to (lat, lon) (ignoring the almost inevitable fact that the 3D average will be deep below the

Finding the Centre of an Abritary Set of Points in Two Dimensions , just average the X and Y coordinates (multiply by a weight if you want) and there is your centroid. More generally, the centroid represents the point designated by the mean (see mean, median, and mode) of the coordinates of all the points in a set. If the boundary is irregular, finding the mean requires using calculus (the most general formula for the centroid involves an integral ).

Comments
  • FYI, with record syntax, data Point = Pt { pointX, pointY :: Double } deriving (Show, Eq), you get the two functions pointX, pointY for free.
  • I think it's worth mentioning that the outermost parentheses are unnecessary.
  • genericLength is controversial. I'd just use fromIntegral (length xs).
  • @leftaroundabout why is genericLength controversial? I thought it was identical to fromIntegral . length, that is a version of length with a polymorphic return value (which really should have been used in the Prelude instead of the monomorphic length that's actually there).
  • @RobinZigmond: I think because for a Double there are (large) values, for which x + 1.0 == x, since the mantissa can no has the "resolution" to increment with one. This thus means that for large lists, the genericLength, will "stop counting" at a given length.
  • @RobinZigmond yeah, that about x + 1 ≡ x is one concrete problem with floats in particular – but in case of Double it would only be an issue for gargantuan lists. But more generally, it just doesn't make sense to carry out lots of additions in a custom number type, when Int is basically always the sweet spot of sufficient size and guaranteed good performance. With genericLength it can easily happen that you do lots of additions in a really inefficient type, instead of doing them all in Int and only converting the result in the end.