omz:forum

    • Register
    • Login
    • Search
    • Recent
    • Popular

    Welcome!

    This is the community forum for my apps Pythonista and Editorial.

    For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.


    draw_heart() now looks really cool

    Pythonista
    2
    7
    4092
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • ccc
      ccc last edited by

      # -*- coding: utf-8 -*-
      # draw_heart.py
      # http://gaming.jhu.edu/~phf/2012/fall/cs112/assignment-02.pdf or
      # https://plus.google.com/app/basic/stream/z12lunmjbx33vh5bt04cilrpelnzcbhoorg0k
      
      #Draw a heart
      import canvas, sys
      from math import sin, cos, pi
      
      w = h = 600
      
      def draw_heart():
          #canvas.move_to(w/2, h/2)
          canvas.move_to(0, 0)
          for t_int in xrange(int(2 * pi * 1000)):
              t = t_int / 1000
              x = 16*(sin(t) ** 3)
              y = 13*cos(t) - 5*cos(2*t) - 2*cos(3*t) - cos(4*t)
              canvas.add_line(x * 150, y * 150)
          canvas.close_path()
          canvas.set_line_width(3)
          canvas.draw_path()
      
      print('Starting...')
      canvas.set_size(w, h)
      draw_heart()
      
      1 Reply Last reply Reply Quote 0
      • bee18
        bee18 last edited by

        Try this one...

        # draw a heart using equation
        import canvas, sys, random
        from console import clear
        from datetime import datetime
        from math import sin, cos, pi
        
        w = h = 600 # canvas size
        detail = random.random() * 100 # larger is slower 
        # almost perfect : 12.485 75.05 125.3
        # half left : 12.525
        # half right : 12.605
        scale = 15 # larger is bigger
        origin = w/2 # plot origin on canvas
        
        def draw_heart(outline = False):
            first = True 
            for t in xrange(int(2*pi * detail)):
                t = t * detail
                # heart equation
                x = 16*(sin(t) ** 3)
                y = 13*cos(t) - 5*cos(2*t) - 2*cos(3*t) - cos(4*t)
                # scale result
                x = origin + x * scale
                y = origin + y * scale + scale*2
                # hide first line
                if first:
                	canvas.move_to(x, y)
                	first = False 
                else: 
                	canvas.add_line(x, y)
            # set color
            canvas.set_fill_color(1,0.5,0.5)
            canvas.set_stroke_color(0.5,0,0)
            canvas.set_line_width(detail/2)
            # draw heart
            if outline: 
            	canvas.draw_path()
            else:
            	canvas.close_path()
            	canvas.fill_path()
        
        clear()
        print 'Calculating... d =',detail
        start = datetime.now()
        canvas.set_size(w,h)
        canvas.draw_rect(0,0, w,h)
        #canvas.draw_line(0,h/2,w,h/2)
        #canvas.draw_line(w/2,0,w/2,h)
        draw_heart(True) # outlined
        draw_heart() # filled
        stop = datetime.now()
        print(stop-start)
        

        Updated with comment and constant separation. Another update, add drawing timer. Another update, add fill mode via function argument. Another update, pick detail value randomly, creating beautiful images out of the equation.

        1 Reply Last reply Reply Quote 0
        • bee18
          bee18 last edited by

          Output sample: https://pic.twitter.com/cGE1W9e3j6

          Output sample:

          1 Reply Last reply Reply Quote 0
          • ccc
            ccc last edited by

            Awesome bee... Just one more nagging question: https://github.com/cclauss/Pythonista_canvas

            1 Reply Last reply Reply Quote 0
            • bee18
              bee18 last edited by

              I couldn't find a floodfill function to fill an arbitrary area with a specified color. If you want to get a smooth edge of the heart, try to play with the detail constant. I found 62.66 seems to be smooth enough. I also found 12.66, 25, 37.66, etc seem to be smooth as well. Try to find other values.

              update: Well, fill_path() does fill the inner part. The problem is how to get smooth edges. So, "correct" detail value seems the only answer. At least with this code. Try my updated code above.

              1 Reply Last reply Reply Quote 0
              • bee18
                bee18 last edited by

                Pick detail value randomly, you'll get beautiful images out of the equation. Check out the latest update.

                1 Reply Last reply Reply Quote 0
                • ccc
                  ccc last edited by

                  Happy Valentines Day!

                  1 Reply Last reply Reply Quote 2
                  • First post
                    Last post
                  Powered by NodeBB Forums | Contributors