• Re: improve a spline

    From Emiliano@21:1/5 to saito on Thu Jun 12 20:08:45 2025
    On Thu, 12 Jun 2025 12:51:58 -0400
    saito <[email protected]> wrote:

    When you run the following code, a canvas comes up and you can
    click-hold your mouse and drag it around to create bezier curves.

    The line is jagged and it has a double curve. I wonder if it is possible
    to make it smooth and reduce it to a plain s shape. Any ideas?

    If by "smooth" you mean antialias, then no, Tk canvas doesn't do antialias.
    As I undertand it, the tkpath package does, but I can't confirm since never used it.

    Regards

    --
    Emiliano

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Arjen@21:1/5 to All on Fri Jun 13 08:28:03 2025
    saito <[email protected]> posted:

    On 6/12/2025 7:08 PM, Emiliano wrote:

    If by "smooth" you mean antialias, then no, Tk canvas doesn't do antialias. As I undertand it, the tkpath package does, but I can't confirm since never used it.


    Thanks for taking a look. This is a piece of very old code from someone
    else and I need to decide whether to improve it or trash it.

    I guess there is no escaping the jagged lines. That is OK. How about
    just making it a simple curve? As it is currently, there are two points where it curves making it look like an S. Any ideas to reduce it to
    simple / relaxed sine curve?

    This is the character of the Bezier smoothing. If you want a curve with
    only a single "bent", you might consider to derive a midpoint from the
    two endpoints and draw a smoothed line (-smooth 1) through THREE points.

    A possible method:
    - Take the vector from point A to point B
    - Determine the normal n to that vector (note: choice of direction!)
    - Use a fraction of the distance between A and B to calculate the new point:

    new point = (A + B)/2 + fraction * distance(A,B) * normal vector

    You have a number of choices here :).

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Emiliano@21:1/5 to saito on Fri Jun 13 10:19:09 2025
    On Thu, 12 Jun 2025 20:49:44 -0400
    saito <[email protected]> wrote:

    On 6/12/2025 7:08 PM, Emiliano wrote:

    If by "smooth" you mean antialias, then no, Tk canvas doesn't do antialias. As I undertand it, the tkpath package does, but I can't confirm since never used it.


    Thanks for taking a look. This is a piece of very old code from someone
    else and I need to decide whether to improve it or trash it.

    I guess there is no escaping the jagged lines. That is OK. How about
    just making it a simple curve? As it is currently, there are two points where it curves making it look like an S. Any ideas to reduce it to
    simple / relaxed sine curve?

    See the "-smooth raw" option. With this option you can define the spline control points. In the following code, circles are knot points (coordinate pairs 0, 3, 6 ...) and the squares are control points (coordinate pairs 1, 2, 4, 5 ...). Try moving the points around.

    Sample code: ==================================================
    package require Tk

    proc lexpr {args} {
    lmap expr $args {uplevel 1 [list expr $expr]}
    }

    proc point-coords {x y} {
    lexpr {$x-5} {$y-5} {$x+5} {$y+5}
    }

    proc move-node {c item idx x y} {
    set x [$c canvasx $x]
    set y [$c canvasy $y]
    $c coords $item [point-coords $x $y]
    $c rchars line {*}[lexpr {$idx*2} {1+2*$idx}] [list $x $y]
    }

    canvas .c -xscrollcommand [list .sx set] -yscrollcommand [list .sy set] ttk::scrollbar .sy -orient vertical -command [list .c yview]
    ttk::scrollbar .sx -orient horizontal -command [list .c xview]
    grid .c .sy -sticky news
    grid .sx -sticky ew
    grid columnconfigure . 0 -weight 1
    grid rowconfigure . 0 -weight 1

    set coords {50 150 100 250 150 50 200 150}
    set idx 0
    .c create line $coords -smooth raw -tags line -splinesteps 20
    foreach {x y} $coords type {oval rectangle rectangle oval} {
    set item [.c create $type [point-coords $x $y] -fill red]
    .c bind $item <B1-Motion> [list move-node %W $item $idx %x %y]
    incr idx
    }
    bind .c <ButtonRelease-1> {%W configure -scrollregion [%W bbox all]}
    .c configure -scrollregion [.c bbox all] ==================================================

    Regards

    --
    Emiliano

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)