我有以下Haskell代码
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)
无论我将什么传递给distributePointsOverCircle,它都会始终为我提供一个包含许多坐标的列表,因为我给出了每个坐标的第一个元素是半径而第二个元素为零的点。显然,这不是点的均匀分布。
我在这里做错了什么?是否有一些类型系统的骗局欺骗了我的电话号码?我要产生的功能是用命令伪代码编写的。
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
最佳答案
我最终得到的是:
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)
如前所述,问题在于您在乘法之前使用了truncate,以便除其他外使用
truncate (pi / 180) == 0
。我也认为您的主要功能有一些错误。