Ist dies eine angemessene Umsetzung der quadratischen Bézier-Funktion in OCaml?

StackOverflow https://stackoverflow.com/questions/145056

  •  02-07-2019
  •  | 
  •  

Frage

Ein Freund kam in einer quadratischen Bézier-Kurven-Funktion in seiner Code-Basis, die eine gigantische Rattennest eines Schalter Tabelle verwendet, um die Berechnung durchzuführen. Er forderte mich auf einen einzigen, kurzen Ausdruck zu finden, die ihm den riesigen Block von Code zu ersetzen erlauben würde.

Bei dem Versuch, zwei verschiedene Kuriositäten gerecht zu werden, dachte ich, ich würde versuchen, die Funktion in OCaml implementieren. Ich bin ein sehr Anfänger OCaml Programmierer und ich bin auch nicht vertraut mit der Funktion und diesem spezifischen Implementierung ist schwer über Google zu bekommen.

Critiques auf, sowohl die Performance / Richtigkeit der Funktion sowie deren Umsetzung sind sehr geschätzt.

Die Umsetzung der quadratische Bézierkurve :

let rec b2 n =
let p1 = -10. in
let p2 = 10. in
let q = n*.n in
let rec b2i n i hd =
  if i > n then
    List.rev hd
  else
    let t = i /. n in
  b2i n (i+.1.) ((((1.-.t)**2.)*.p1+.(2.*.t*.(1.-.t)*.q)+.(t**2.)*.p2) :: hd)
in b2i n 0. []
;;
let floatprint lst = List.iter (fun f -> Printf.printf "%f; " f) lst ;;
floatprint (b2 8.);;
War es hilfreich?

Lösung

b2 ist nicht rekursiv, so dass keine Notwendigkeit für [rec lassen b2 n =]. Da n ändert sich nie, keine Notwendigkeit, es als Argument müssen B2I, nur n aus dem umschließenden Bereich zu verwenden. Ihre innere Funktion auf p0, p1 und p2 abhängen sollte, aber ich sehe es in Abhängigkeit von -10, n ** 2 und 10. Die Funktion hat auch die Form einer Karte von [0.0. 1,0; 2,0; ...; n.0] auf die endgültigen Werte. Könnten Sie es schreiben:

let b i = 
  let t = i /. n in
  let tminus = (1.-.t) in
  (tminus *. tminus *. p0) +. (2. *. t *. tminus *. p1) +. (t *. t * p2)
in
List.map b ([generate list 1.0; 2.0; ... n.0])

Eine Funktion die Liste 1.0 zu generieren ... n.0 sein könnte: (für kleine n)

let rec count m n = if m > n then [] else m :: (count (m+.1.) n)

Andere Tipps

Ich habe zwei Vorschläge:

Sie sollten List.rev rufen nach b2i kehrt so kann ocaml ausnutzen es ist Schwanz-Rekursion Optimierungen. Ich bin nicht sicher, wie gut ocaml mit der aktuellen Implementierung befassen wird, List.rev ist Schwanz-rekursive though. Sie werden bemerken, dass in diesen Beitrag es gemacht wird wie das.

Sie können aber auch die Auflösung der Iteration machen ein optionales Argument wie ?(epsilon=0.1) sein.

Als ocaml Programmierer ich viel falsch nicht beiseite sehen hier aus, dass --as solange P1 und P2 in der Tat Konstanten sind. Kompilieren Sie es nach unten und sehen, was der Unterschied in der Montage ist List.rev zwischen sich bewegenden innen oder aus dem Schwanz-Rekursion.

Dies kann picayune, aber hd ist kein guter Name für einen Listenparameter. List.hd ist eine Standardfunktion, die das erste Element einer Liste zurück. Mit hd als Name für eine Liste zu Verwirrung führen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top