Reputation: 2111
I have the following Haskell code
import Data.Int
import System.Environment
type Coord = (Int16, Int16)
distributePointsOverCircle :: Int16 -> Int16 -> [Coord]
distributePointsOverCircle points radius =
[ (xOf point, yOf point) | point <- [1..points] ]
where
xOf x = abstract cos x
yOf x = abstract sin x
abstract :: RealFrac a => ( a -> a ) -> Int16 -> Int16
abstract f x = (radius *) . truncate . f . fromIntegral $ (angleIncrement * x) * truncate (pi / 180)
angleIncrement = div 360 points
main = do
[a,b] <- getArgs
print $ distributePointsOverCircle (read a) (read b)
No matter what I pass to distributePointsOverCircle, it consistently gives me a list of however many Coords as I give points where each Coord's first element is the radius and second element is zero. Obviously this is not an even distribution of points.
What am I doing wrong here? Is there some type-system trickery fudging my numbers? The function I am trying to produce, written in an imperative pseudocode would be.
distributePointsOverCircle( numberOfPoints, radius )
angleIncrement = 360 / numberOfPoints
points = []
for i in 0 to (numberOfPoints -1)
p = Point()
p.x = (radius * cos((angleIncrement * i) * (PI / 180)))
p.y = (radius * sin((angleIncrement * i) * (PI / 180)))
points[i] = p
return points
Upvotes: 3
Views: 473
Reputation: 9891
Here is what I ended up with:
import Data.Int
import System.Environment
type Coord = (Int16, Int16)
distributePointsOverCircle :: Int16 -> Int16 -> [Coord]
distributePointsOverCircle points radius =
[ (xOf point, yOf point) | point <- [1..points] ]
where
xOf x = abstract cos x
yOf x = abstract sin x
iRadius = fromIntegral radius
angleIncrement = div 360 points
abstract f x = round . (iRadius *) . f $ angle * (pi / 180)
where
angle = fromIntegral $ angleIncrement * x
main = do
[a,b] <- getArgs
print $ distributePointsOverCircle (read a) (read b)
As already mentioned, the problem was that you used truncate before multiplying so that among other things truncate (pi / 180) == 0
. I also think you had some errors in your main function.
Upvotes: 2
Reputation: 523614
It gives you a list of (r, 0) because truncate (pi / 180) == 0
. Remove the truncate
and the code should work fine.
abstract f x = (radius *) . truncate . f $ fromIntegral (angleIncrement * x) * (pi / 180)
Upvotes: 5