How to mirror/flip a object?



  • Hello World, i have a struggle on a very simple task - how can i mirror/flip a bezier path object (or a text) horizontal and vertical?

    thanks in advance



  • My goal is to draw a shadow, so I have to mirror the letter. (i achieved scaling, skewing, but not flipping)

    newPage(1000, 1000)
    
    font('Skia')
    fontSize(600)
    fill(0.79, 0.52, 0.67)
    text('A', (300, 200))
    fill(0)
    scale(x=1, y=0.05)
    text('A', (300, 800))
    


  • Did you test something like negative scaling?

    scale(-1)
    scale(1, 1/3)



  • Hello @ricardov Yes, i tried negative scaling, but it gives no result. It gives no error, but there is also nothing happening...



  • the mirrored drawing is probably happening outside your canvas. keep in mind that every transformation (scale, skew, rotation, etc) is always starting from the origin. so a mirroring from the default origin (left, bottom corner) will be to the left or below your canvas. see the example below with a shifted origin.

    pw = 1000
    ph = 400
    txt = "SHADE"
    newPage(pw, ph)
    translate(0, 160) # shift the origin up a bit
    fontSize(300)
    text(txt, (pw/2, 0), align = 'center')
    scale(x=1, y=-.5) # the mirroring
    text(txt, (pw/2, 0), align = 'center')
    


  • Hey @jo - thank you very much! That was the issue - damn, i am still in trouble with the the basics. Actually i am pretty stoked to have you here responding, because i am messing around with your code... 😉 i`d love to ad different lissajous curves to my blobbish letters, and i hoped changing the numbers (a = 2 # 2, 3, 4 are decent values) would do the trick - but it does not really change that much - sometimes even the loop is not longer working. Would you mind having a look at my codemess? (i mean, your code - and my mess 😄 )

    A-Blob



  • # --------------------------
    #  imports
    
    import sys
    sys.path.append("..")
    from helper_functions import *
    
    # --------------------------
    #  settings
    
    p_w, p_h = 1000, 1000
    margin = 40
    dia = 4
    steps = 600
    
    # lissajous values
    a = 2 # 2, 3, 4 are decent values
    b = a + 1
    delta = 0 # pi/2, pi/3, pi/4
    
    f_name = "habaroll8"
    
    axes = ['wght', 'wdth'] 
    
    # --------
    axis1_min = listFontVariations(f_name)[axes[0]]['minValue']
    axis1_def = listFontVariations(f_name)[axes[0]]['defaultValue']
    axis1_max = listFontVariations(f_name)[axes[0]]['maxValue']
    
    axis2_min = listFontVariations(f_name)[axes[1]]['minValue']
    axis2_def = listFontVariations(f_name)[axes[1]]['defaultValue']
    axis2_max = listFontVariations(f_name)[axes[1]]['maxValue']
    
    
    axis_w = p_w - 2 * margin
    axis_h = p_h - 2 * margin
    
    def_x = map_val(axis1_def, axis1_min, axis1_max, 0, axis_w)
    def_y = map_val(axis2_def, axis2_min, axis2_max, 0, axis_h)
    
    # --------------------------
    #  functions 
    
    def a_page():
        newPage(p_w,p_h)
        fill(1)
        rect(0, 0, p_w, p_h)
        translate(margin, margin)
    
        fill(0.92, 0.90, 0.87)
        rect(0, 0, axis_w, axis_h)
    
        font(f_name)
        fontSize(820 )
    
    
    # --------------------------
    #  Drawings 
    
    pts = []
    for st in range(steps):
    
        # newDrawing()
        a_page()
    
        angle = 2 * pi / steps * st
    
        x = .5 + .5 * sin( a * angle + delta )
        y = .5 + .5 * sin( b * angle )
    
    
    
        curr_axis1 = ip(axis1_min + 20, axis1_max - 20, x)
        curr_axis2 = ip(axis2_min + 20, axis2_max - 20, y)
        var_values = { axes[0] : curr_axis1, axes[1] : curr_axis2 }    
        fontVariations(**var_values)
        
        #black ring to avoid the background "bleed through"
        fill(None)
        stroke(0)
        strokeWidth(60)
        oval(125, 95, 700, 700) 
        
        # the black part (fake 3D)
        stroke(0)
        strokeWidth(4)
        fill(0)
        text('A', (axis_w/2, axis_h/8), align = 'center') 
        
        # the pink blob letter
        stroke(None)
        fill(0.79, 0.52, 0.67)
        scale(x=1.25, y=1.25)
        translate(x=-95, y=-80)
        text('A', (axis_w/2, axis_h/8), align = 'center') 
        
        # the blob shadow (would be great to have the shadow behind the pink blob!) 
        fill(0)
        translate(-120, 110)
        scale(x=0.9, y=-.05)
        skew(25, 0)
        rotate(-3)
        text('A', (axis_w/2, axis_h/8), align = 'center') 
    
    
      
    saveImage('lissajous_var_test12.gif')
    
    


  • @habakuk nice to read that you can use some of the code!

    about the lissajous: I am not sure what exactly you want to achieve. the german wiki entry has vizualisations for a few values. you might want to change the value for a and b and also delta, eg:

    a = 1 
    b = 3
    delta = pi/4
    

    I do not have your variable font so I cannot test this but I was wondering why you added the plus and minus 20 here:

    curr_axis1 = ip(axis1_min + 20, axis1_max - 20, x)
    curr_axis2 = ip(axis2_min + 20, axis2_max - 20, y)
    

    lastly if you want to draw the shadow in the back, just put the lines of code before you call the pink drawing. you might then use the savedState() so draw it without the mirroring.

    good luck, jo!



  • Hallo @jo thanks alot - at the moment i use the lissajus only to create different nice looking loops. I changed the values as you suggested and of course it is working now and delivers a new nice looking loop. 😉
    I`d love to make some more loops with more "natural, subtle and slow" movements. I saw your great visualisations of the different variable font movements and hoped to create a custom path to do so - but i failed...

    if you like to play around with my very first 5 letter variable font (HABKU) you are very welcome. http://habaland.ch/images/habaroll8GX.ttf

    i added the the plus and minus to avoid the font doing the whole move to the min and max, because the backgraound would be visible then. (but most likely i created only a mess 😄 ) and by the way, i hate the black circle i had to ad "behind the scene" - id love o have a cleaner solution.

    ...at the moment i am trying to figure out where to append the savedState() without messing everything up...

    greetings from Bern