]> gitweb.factorcode.org Git - factor.git/commitdiff
Splines: catmull-rom, bezier curve, cubic hermite, kochanek-bartels
authorErik Charlebois <erikcharlebois@gmail.com>
Tue, 16 Feb 2010 11:26:36 +0000 (03:26 -0800)
committerErik Charlebois <erikcharlebois@gmail.com>
Tue, 16 Feb 2010 11:26:36 +0000 (03:26 -0800)
extra/math/splines/authors.txt [new file with mode: 0644]
extra/math/splines/splines-docs.factor [new file with mode: 0644]
extra/math/splines/splines.factor [new file with mode: 0644]
extra/math/splines/summary.txt [new file with mode: 0644]
extra/math/splines/testing/authors.txt [new file with mode: 0644]
extra/math/splines/testing/testing.factor [new file with mode: 0644]
extra/math/splines/viewer/authors.txt [new file with mode: 0644]
extra/math/splines/viewer/viewer.factor [new file with mode: 0644]

diff --git a/extra/math/splines/authors.txt b/extra/math/splines/authors.txt
new file mode 100644 (file)
index 0000000..6f03a12
--- /dev/null
@@ -0,0 +1 @@
+Erik Charlebois
diff --git a/extra/math/splines/splines-docs.factor b/extra/math/splines/splines-docs.factor
new file mode 100644 (file)
index 0000000..62ff141
--- /dev/null
@@ -0,0 +1,44 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: help.markup help.syntax math ;
+IN: math.splines
+
+HELP: <bezier-curve>
+{ $values
+    { "control-points" "sequence of control points same dimension" }
+    { "polynomials" "sequence of polynomials for each dimension" }
+}
+{ $description "Creates bezier curve polynomials for the given control points." } ;
+
+HELP: <catmull-rom-spline>
+{ $values
+    { "points" "points on the spline" } { "m0" "initial tangent vector" } { "mn" "final tangent vector" }
+    { "polynomials-sequence" "sequence of sequences of polynomials" }
+}
+{ $description "Creates a sequence of cubic hermite curves (each a sequence of polynomials) passing through the given points and generating tangents for C1 continuity." } ;
+
+HELP: <cubic-hermite-curve>
+{ $values
+    { "p0" "start point" } { "m0" "start tangent" } { "p1" "end point" } { "m1" "end tangent" }
+    { "polynomials" "sequence of polynomials" }
+}
+{ $description "Creates a sequence of polynomials (one per dimension) for the curve passing through " { $emphasis "p0" } " and " { $emphasis "p1" } "." } ;
+
+HELP: <cubic-hermite-spline>
+{ $values
+    { "point-tangent-pairs" "sequence of point and tangent pairs" }
+    { "polynomials-sequence" "sequence of sequences of polynomials" }
+}
+{ $description "Creates a sequence of cubic hermite curves (each a sequence of polynomials) passing through the given points with the given tangents." } ;
+
+HELP: <kochanek-bartels-curve>
+{ $values
+    { "points" "points on the spline" } { "m0" "start tangent" } { "mn" "end tangent" } { "tension" number } { "bias" number } { "continuity" number }
+    { "polynomials-sequence" "sequence of sequence of polynomials" }
+}
+{ $description "Creates a sequence of cubic hermite curves (each a sequence of polynomials) passing through the given points, generating tangents with the given tuning parameters." } ;
+
+ARTICLE: "math.splines" "Common parametric curves."
+"The curve creating functions create sequences of polynomials, one for each degree of the input points. The spline creating functions create sequences of these curve polynomial sequences. The " { $vocab-link "math.splines.viewer" } " vocabulary provides a gadget to evaluate the generated polynomials and view the results.";
+
+ABOUT: "math.splines"
diff --git a/extra/math/splines/splines.factor b/extra/math/splines/splines.factor
new file mode 100644 (file)
index 0000000..dc22224
--- /dev/null
@@ -0,0 +1,84 @@
+! Copyright (C) 2010 Erik Charlebois
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors combinators kernel locals math math.combinatorics
+math.polynomials opengl.gl sequences ui.gadgets ui.gadgets.panes
+ui.render arrays grouping math.vectors assocs
+ui.gestures ;
+IN: math.splines
+
+<PRIVATE
+:: bernstein-polynomial-ith ( n i -- p )
+    n i nCk { 0 1 } i p^ { 1 -1 } n i - p^ p* n*p ;
+
+:: hermite-polynomial ( p0 m0 p1 m1 -- poly )
+    p0
+    m0 
+    -3 p0 * -2 m0 * + 3 p1 * + m1 neg +
+    2 p0 * m0 + -2 p1 * + m1 +
+    4array ;
+
+:: kochanek-bartels-coefficients ( tension bias continuity -- s1 d1 s2 d2 )
+    1 tension -
+    [
+        1 bias +
+        [ 1 continuity + * * 2 / ]
+        [ 1 continuity - * * 2 / ] 2bi
+    ]
+    [
+        1 bias -
+        [ 1 continuity - * * 2 / ]
+        [ 1 continuity + * * 2 / ] 2bi
+    ] bi ;
+
+:: kochanek-bartels-tangents ( points m0 mn c1 c2 -- tangents )
+    points 3 clump [
+        first3 :> ( pi-1 pi pi+1 )
+        pi pi-1 v- c1 v*n
+        pi+1 pi v- c2 v*n v+
+    ] map
+    m0 prefix
+    mn suffix ;
+PRIVATE>
+
+:: <bezier-curve> ( control-points -- polynomials )
+    control-points
+    [ length 1 - ]
+    [ first length [ { 0 } ] replicate ]
+    bi :> ( n acc )
+
+    control-points [| pt i |
+        n i bernstein-polynomial-ith :> poly
+        pt [| v j |
+            j acc [ v poly n*p p+ ] change-nth
+        ] each-index
+    ] each-index
+    acc ;
+    
+:: <cubic-hermite-curve> ( p0 m0 p1 m1 -- polynomials )
+    p0 length iota [
+        {
+            [ p0 nth ] [ m0 nth ]
+            [ p1 nth ] [ m1 nth ]
+        } cleave
+        hermite-polynomial
+    ] map ;
+
+<PRIVATE
+: (cubic-hermite-spline) ( point-in-out-triplets -- polynomials-sequence )
+    2 clump [
+        first2 [ first2 ] [ [ first ] [ third ] bi ] bi* <cubic-hermite-curve>
+    ] map ;
+PRIVATE>
+
+: <cubic-hermite-spline> ( point-tangent-pairs -- polynomials-sequence )
+    2 clump [ first2 [ first2 ] bi@ <cubic-hermite-curve> ] map ;
+
+:: <kochanek-bartels-curve> ( points m0 mn tension bias continuity -- polynomials-sequence )
+    tension bias continuity kochanek-bartels-coefficients :> ( s1 d1 s2 d2 )
+    points m0 mn
+    [ s1 s2 kochanek-bartels-tangents ]
+    [ d1 d2 kochanek-bartels-tangents ] 3bi :> ( in out )
+    points in out [ 3array ] 3map (cubic-hermite-spline) ;
+
+: <catmull-rom-spline> ( points m0 mn -- polynomials-sequence )
+    0 0 0 <kochanek-bartels-curve> ;
diff --git a/extra/math/splines/summary.txt b/extra/math/splines/summary.txt
new file mode 100644 (file)
index 0000000..229b05e
--- /dev/null
@@ -0,0 +1 @@
+Common parametric curves
diff --git a/extra/math/splines/testing/authors.txt b/extra/math/splines/testing/authors.txt
new file mode 100644 (file)
index 0000000..67cf648
--- /dev/null
@@ -0,0 +1 @@
+Erik Charlebois
\ No newline at end of file
diff --git a/extra/math/splines/testing/testing.factor b/extra/math/splines/testing/testing.factor
new file mode 100644 (file)
index 0000000..bbb5cd6
--- /dev/null
@@ -0,0 +1,49 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: locals math.splines math.splines.viewer arrays ;
+IN: math.splines.testing
+
+: test1 ( -- )
+    {
+        { { 0 0 } { 0 200 } }
+        { { 100 50 } { 0 -200 } }
+        { { 300 300 } { 500 200 } }
+        { { 400 400 } { 300 0 } }
+    } <cubic-hermite-spline> { 50 100 } 4 spline. ;
+
+: test2 ( -- )
+    {
+        { 50 50 }
+        { 100 100 }
+        { 300 200 }
+        { 350 0 }
+        { 400 400 }
+    } { 0 100 } { 100 0 } <catmull-rom-spline> { 100 50 } 50 spline. ;
+
+:: test3 ( x y z -- )
+    {
+        { 100 50 }
+        { 200 350 }
+        { 300 50 }
+    } { 0 100 } { 0 -100 } x y z <kochanek-bartels-curve> { 50 50 } 1000 spline. ;
+
+: test4 ( -- )
+    {
+        { 0 5 }
+        { 0.5 3 }
+        { 10 10 }
+        { 12 4 }
+        { 15 5 }
+    } <bezier-curve> 1array { 100 100 } 100 spline. ;
+
+: test-splines ( -- )
+    test1 test2
+    1 0 0 test3
+    -1 0 0 test3
+    0 1 0 test3
+    0 -1 0 test3
+    0 0 1 test3
+    0 0 -1 test3
+    test4 ;
+    
+
diff --git a/extra/math/splines/viewer/authors.txt b/extra/math/splines/viewer/authors.txt
new file mode 100644 (file)
index 0000000..67cf648
--- /dev/null
@@ -0,0 +1 @@
+Erik Charlebois
\ No newline at end of file
diff --git a/extra/math/splines/viewer/viewer.factor b/extra/math/splines/viewer/viewer.factor
new file mode 100644 (file)
index 0000000..f1ec1a2
--- /dev/null
@@ -0,0 +1,49 @@
+! Copyright (C) 2010 Erik Charlebois.
+! See http://factorcode.org/license.txt for BSD license.
+USING: accessors kernel locals math math.order math.polynomials
+math.splines opengl.gl sequences ui.gadgets ui.gadgets.panes ui.render
+arrays ;
+IN: math.splines.viewer
+
+<PRIVATE
+: eval-polynomials ( polynomials-seq n -- xy-sequence )
+    [
+        [ 1 + iota ] keep [
+            /f swap [ polyval ] with map
+        ] curry with map
+    ] curry map concat ;
+PRIVATE>
+
+TUPLE: spline-gadget < gadget polynomials steps spline-dim ;
+
+M: spline-gadget pref-dim* spline-dim>> ;
+
+M:: spline-gadget draw-gadget* ( gadget -- )
+    0 0 0 glColor3f
+
+    gadget [ polynomials>> ] [ steps>> ] bi eval-polynomials :> pts
+
+    pts [ first ] [ max ] map-reduce  :> x-max
+    pts [ first ] [ min ] map-reduce  :> x-min
+    pts [ second ] [ max ] map-reduce :> y-max
+    pts [ second ] [ min ] map-reduce :> y-min
+
+    pts [
+        [ first x-min - x-max x-min - / gadget spline-dim>> first * ]
+        [ second y-min - y-max y-min - / gadget spline-dim>> second * ] bi 2array
+    ] map :> pts
+    
+    GL_LINE_STRIP glBegin
+    pts [
+        first2 neg gadget spline-dim>> second + glVertex2f
+    ] each
+    glEnd ;
+
+:: <spline-gadget> ( polynomials dim steps -- gadget )
+    spline-gadget new
+    dim >>spline-dim
+    polynomials >>polynomials 
+    steps >>steps ;
+
+: spline. ( curve dim steps -- )
+    <spline-gadget> gadget. ;