Vector Graphics Library

  • FeynmanLogomaker
    28th Jan 2014 Member 0 Permalink

    The script itself can be found here: 

    https://github.com/FeynmanTech/TPT-Vector-Graphics (it's main.lua). 

     

    This library can be used by anyone, no credit needed, in a script or by itself.

     

    UPCOMING:

         Automatic calculating of gap at each step - I've found the algorithms, I just need to implement them. -        Done for ellipse

         Better line function, that works lower-level than repeated calling of a point function

     

    The main functions are:

         aa.point

              Usage: aa.point ( x coordinate , y coordinate )

         

         aa.line    

              Usage: aa.line ( start x , start y , end x , end y )

     

         aa.star

              Usage: aa.star ( dist. between lines (degrees) , radius )

              This was just added for testing different line algorithms

     

         aa.ellipse

              Usage: aa.ellipse ( x , y , width , height [, accuracy [, gap between points ]] )

              Gap takes some experimenting to find a good level.

     

         aa.bezier

              Usage: aa.bezier ( x1 , y1 , x2 , y2 , control x1 , control y1 , control x2 , control y2

     

         aa.bezrandom

              Usage: aa.bezrandom ( )

              This was just used for testing various Bézier curve algorithms

     

         Note: the point and line functions both have rasterized, aliased counterparts in the 'ra' table.

     

    I will be posting detailed instructions for it soon.

     

    Please Note: The ellipse and bezier functions are still not working perfectly - they sometimes draw with poor antialiasing or with gaps between drawn lines. The ellipse is more or less usable, but the Bézier curves are still under development.

     

    You can find examples of the library in this save:

     

    Edited 3 times by FeynmanLogomaker. Last: 30th Jan 2014
  • bimmo_devices
    29th Jan 2014 Member 0 Permalink

    yummy. Sort of art-plotting, but very low level. I like it.

  • mniip
    29th Jan 2014 Developer 0 Permalink
    @FeynmanLogomaker (View Post)
    When drawing a circle, gap should be 2pi/R (afaik). When drawing an ellipse, the gap is an elliptic integral which is not calculable, you can approximate first few terms. And for beziers it's some polynomial i don't even remember.
    I've done this exact thing before, and it was way more antialiased than yours
    Edited 2 times by mniip. Last: 30th Jan 2014
  • FeynmanLogomaker
    29th Jan 2014 Member 0 Permalink

    Ok, so you've done this before. So what? I'm not doing this to compete with you.

  • boxmein
    29th Jan 2014 Former Staff 1 Permalink
    @FeynmanLogomaker (View Post)
    Despite his tone he is actually suggesting useful things and improvements to consider. And not in the TPT sense where useful is thrown around every Aluminum suggestion, but actually relevantly useful.

    Also, lol, nice job with the library. Your antialiasing looks a bit wonky which you're reportedly getting on.
    Edited once by boxmein. Last: 29th Jan 2014
  • FeynmanLogomaker
    29th Jan 2014 Member 0 Permalink

    Thanks :)

    By the way, yeah, I know he's saying stuff that could be useful, but when he throws in, "I've dont this exact thing before, and it was way more antialiased than yours", that sort of sends a mixed message...

     
     
  • mniip
    30th Jan 2014 Developer 1 Permalink
    @FeynmanLogomaker (View Post)
    Your pixel function is weird. why are you turning the color into a hex string, splitting it, then rearranging in a string again...
    Why are you swapping begin and end points in your line function? It's not like it matters.
    Also your bezier function is broken, the step in the for loop is only evaluated once. Besides it draws the bezier as series of lines, which ends up in there being bright dots here and there on the curve.

    Here're ellipses drawn using your algorithm, but using raster points and 5x gap:
    poorly rendered ellipses
    You can see that even in the topmost ellipse, the gap is almost always under 5, you're drawing the points way too close. Besides on thin ellipses the thing is getting even worse near the ends.

    Here's my algorithm for comparison
    well-rendered ellipses

    You seem to get the idea correctly: to build a vector curve you need to distribute the points along the curve.
    If you're familiar with the arc length formula, it should be easy to derive that to move by 1 unit along a circle you need to advance by 1/R radians:
    arc length of 1/R rad is 1
    The stuff gets more complex with ellipses, a distance along an ellipse transorms into solving integral of sqrt(1-a*sin^2(x)) by dx, which is an elliptic integral of second kind and is not solvable. However a good approximation can be done if you assume the ellipse to be a circle of the radius inverse to the point you are standing in:
    image
    (This depiction of relations between the angles on ellipses and circles is totally incorrect though, but it gives the idea. The radial angle is not linear when moving along an ellipse.)
    Notice the swap of Rx and Ry
    That approximation might be repeated once more if you use the result as the new "current" point, or use the middle between new and old. The series converge really fast, so in my code I only use 2 iterations. The series however fails to converge horribly if your overall starting point (t=0) is at a radius which is way smaller then the other one. To avoid that you just start in a different location.

    Here's my code:

    local function ellipticdist(rx, ry, d)
    return sqrt((rx * sin(d)) ^ 2 + (ry * cos(d)) ^ 2)
    end

    function vec.ellipse(x, y, rx, ry, c)
    local off = atan2(ry, rx) -- make sure we don't start at 0 if rx is small
    local d = off
    while d < 2 * pi + off do
    vec.pixel(x + rx * sin(d), y + ry * cos(d), c)
    -- 2 elements is pretty much enough
    local step = 1 / ellipticdist(ry, rx, d)
    step = 1 / ellipticdist(ry, rx, d + step / 2)
    d = d + step
    end
    end


    Here's my whole source anyway: http://qp.mniip.com/p/fn

    Beziers? Uh... I have the code but I'm not ready to explain it yet.
    Edited 2 times by mniip. Last: 30th Jan 2014
  • FeynmanLogomaker
    30th Jan 2014 Member 1 Permalink

    Do you mind if I use your algorithms? They do seem to work much better than mine.

     

    (And the swapping of end points in my line function was left over from my old algorithm, I should delete it)

    Edited once by FeynmanLogomaker. Last: 30th Jan 2014
  • mniip
    30th Jan 2014 Developer 2 Permalink
    @FeynmanLogomaker (View Post)
    Yeah, feel free to, to some extent
  • FeynmanLogomaker
    30th Jan 2014 Member 1 Permalink

    Great, thanks! I'll make sure to give you credit.