Оценка многих функций в одной точке с использованием карты

С помощью Elm share-elm.com мне удалось сделать отличную картинку, и любые советы по оптимизации кода были бы полезны, но я остановлюсь на последних двух строках:

xflip : (number, number) -> (number, number)
xflip pt = ( -1*(fst pt), snd pt)

rot : (number, number) -> (number, number)
rot pt = ( -1*(snd pt), fst pt)

mul : number -> (number, number) -> (number, number)
mul a b = (a*(fst b), a*(snd b))

add : (number, number) -> (number, number) -> (number, number)
add a b = ((fst a)+(fst b), (snd a)+(snd b))

-- implementations of the symmetries of hilbert space curve

t1 : (number, number) -> (number, number)
t1 b = (add (mul 0.5 (-100,-100)) ((mul 0.5) (rot (rot(rot (xflip b))) )))

t2 : (number, number) -> (number, number)
t2 b = (add (mul 0.5 (-100,100)) ((mul 0.5) (b)))

t3 : (number, number) -> (number, number)
t3 b = (add (mul 0.5 (100,100)) ((mul 0.5) ( b)))

t4 : (number, number) -> (number, number)
t4 b = (add (mul 0.5 (100,-100)) ((mul 0.5) (rot (xflip b) )))

--

t : [(number, number)] -> [(number, number)]
t z = (map t1 z) ++ (map t2 z) ++ (map t3 z) ++ (map t4 z) 

Я не знаю, является ли это лучшим решением для определения сложения векторов или 2D-преобразований, но мне нужно было как-то это сделать. Часто делаю с векторной графикой на самой графике, я работаю со списком точек, прежде чем они станут Path типы.

Был ли это лучший способ перебора функции вращения rot? Мне нужно было повернуть на 90 градусов влево и затем вправо. Так что я повернул налево 3 раза:

rot (rot(rot (xflip b))) 

На главный вопрос, можно ли упорядочить мои последние две строки:

t : [(number, number)] -> [(number, number)]
t z = (map t1 z) ++ (map t2 z) ++ (map t3 z) ++ (map t4 z) 

Список номеров станет моим Path объекты и t1 через t4 являются функциями. Я подумал, может быть, я мог бы перебрать эти функции с map, Это работает в случаях, которые я пробовал на Github Gist: https://gist.github.com/MonsieurCactus/ef285584f1588289b477 Вот что я попробовал:

t : [(number, number)] -> [(number, number)]
t z = map ( \f -> (map f z)) [t1, t2, t3 ,t4]

Компилятор Elm вернул сообщение об ошибке:

[1 of 1] Compiling Main                ( Main.elm )
Type error on line 49, column 7 to 46:
        map (\f -> map f z) [t1,t2,t3,t4]

   Expected Type: (Float)
     Actual Type: _List

Type error on line 49, column 7 to 46:
        map (\f -> map f z) [t1,t2,t3,t4]

   Expected Type: Float
     Actual Type: (Float, Float)

Может быть, я должен был попытаться написать функцию [Path] -> [Path] но тогда я должен получить список точек и изменить их в любом случае.

1 ответ

Оптимизация последних двух строк

Ваша попытка сократить определение t в правильном направлении. Но потому что вы отображаете список функций ([t1,t2,t3,t4]), и внутри функции отображения вы отображаете список точек z, вы получите список списков точек ([[(number,number)]] вместо [(number, number)]).
Так что вам еще нужно concat этот список списков. Вы также можете использовать concatMap вместо свободного concat а также map:

t : [(number, number)] -> [(number, number)]
t z = concatMap ( \f -> (map f z)) [t1, t2, t3 ,t4]

Итерация rot

Если вы не возражаете против использования Float везде вместо number Вы можете изменить свой rot функция, чтобы сделать поворот, чтобы выполнить. Используя некоторые основные функции, вы можете написать что-то вроде:

rot' : Float -> (Float, Float) -> (Float, Float)
rot' angle point = 
    let (r,th) = toPolar point
        th' = th + angle
    in fromPolar (r,th')

rot = rot' (degrees 90)
Другие вопросы по тегам