Process a heart curve

edited October 2013 in How To...

Hey I would like to process a heart curve by using this equation:

(x^2 + y^2 - 1)^3 - x^2 * y^3 = 0

I know that I have to use pow() etc. but I don't know how I get it in the programm togehter at all. Thank you for help!

Comments

  • edited October 2013

    in my understanding you have to get rid of the zero and re-formulate your formula to something like

    y = .......................x.......x....................

    when you have that just for-loop through 0 to 1000 and calculate and display all the y-values for the current x-value....

    my own naive approach needs two minutes and has no result

    // 
    void setup()
    {
      size( 800, 800, P2D );
      stroke(255);
      fill(255);
      background(0);
      println("start"); 
      //
    } // setup
    
    void draw()
    {
      background(0);
      float x=0;
      float y=0;
    
      for (int x1=0; x1<3000; x1+=1) {
        for (int y1=0; y1<3000; y1+=1) {
          // (x^2 + y^2 - 1)^3 - x^2 * y^3 = 0
          float bracket1 = pow(x, 2) + pow(y, 2) - 1;
          float full1 = pow(bracket1, 3)  - pow(x, 2) * pow(y, 3); 
          if ( full1 == 0 ) {
            point (x, y);
            println ("found "+x);
          } // if
          y+=.01;
        } // for
        x+=.01;
      } // for 
      println("done"); 
      noLoop();
    } // draw
    //
    
  • edited October 2013

    Although the equation you have does describe a heart shape (mathematically) it is not in a form that can easily be computed. The solution is to look for a pair of parametric formulae that describe a heart shape. After a little googling I found these

    x = 16 * sin^3(t)

    y = 13cos(t) - 5 * cos(2t) -2cos(3t) - cos(4*t)

    and t varies in the range >= -PI and <= PI

    any way so I created this sketch which using these formulae

    PVector p0 = new PVector();
    PVector p1 = new PVector();
    float m = 6;
    
    public void setup() {
      size(250, 250);
    
      float t, tmin = -PI, tmax = PI, tdif = 0.01;
      t = tmin;
      translate(width/2, height/2);
      stroke(255, 0, 0);
      strokeWeight(2);
      background(255);
      calcPos(p0, t, m);
      while (t < tmax) {
        calcPos(p1, t, m);
        line(p0.x, p0.y, p1.x, p1.y);
        p0.set(p1);
        t += tdif;
      }
      println("DONE");
    }
    
    
    public void calcPos(PVector v, float t, float size) {
      v.x = 16 * pow( sin(t), 3);
      v.y = -(13*cos(t) - 5 * cos(2*t) -2*cos(3*t) - cos(4*t));
      v.mult(size);
    }
    
  • edited October 2013

    1st time posting in the new forum.
    Still no avatar and dunno whether code is gonna be formatted yet.
    Anyways, here it is a slightly modified code. 8-X

    /** 
     * Heart Curve (v2.0)
     * by  Quark (2013/Oct)
     * mod GoToLoop
     * 
     * forum.processing.org/two/discussion/48/process-a-heart-curve
     */
    
    final static float TDIM = 11., TMIN = -PI, TMAX = PI, TDIF = .005;
    
    void setup() {
      size(400, 350);
      noLoop();
      smooth(4);
    
      stroke(#FF0000);
      strokeWeight(4);
      background(-1);
      translate(width/2, height/2.3);
    
      final PVector p0 = new PVector(), p1 = new PVector();
      float t = TMIN;
    
      calcPos(p0, t, TDIM);
    
      while (t < TMAX) {
        calcPos(p1, t += TDIF, TDIM);
        line(p0.x, p0.y, p1.x, p1.y);
        p0.set(p1);
      }
    }
    
    static final void calcPos(PVector v, float t, float s) {
      v.x = sin(t);
      v.x = 16 * v.x * v.x * v.x;
    
      v.y = -13*cos(t) + 5*cos(2*t) + 2*cos(3*t) + cos(4*t);
    
      v.mult(s);
    }
    
  • There is an alternative to using parametric equations and that is using polar coordinates where a position is defined by the distance from the origin (r) and the angle made with the x axis (t). This heart was drawn with the equation

    r = (sin(t) * sqrt(abs(cos(t))))/(sin(t) + 1.4) - 2*sin(t) + 2;

    where again t goes from -PI to +PI

    and then converting the polar to Cartesian coordinates

    PVector p0 = new PVector();
    PVector p1 = new PVector();
    float m = 20;
    
    public void setup() {
      size(250, 250);
    
      float t, tmin = -PI, tmax = PI, tdif = 0.01;
      t = tmin;
      translate(width/2, height/2);
      stroke(255, 0, 0);
      strokeWeight(2);
      background(255);
      polarPos(p0, t, m);
      while (t < tmax) {
        polarPos(p1, t, m);
        line(p0.x, p0.y, p1.x, p1.y);
        p0.set(p1);
        t += tdif;
      }
      println("DONE");
    }
    
    public void polarPos(PVector v, float t, float size){
      float sint = sin(t), cost = cos(t);
      float r = (sint * sqrt(abs(cost)))/(sint + 1.4) - 2*sint + 2;
      // convert to Cartesian coordinates``
      v.x = size * r * cost;
      v.y = - size * r * sint;
    }
    
  • edited October 2013

    Thanks to everyone who helped! The solution from quark works perfectly! 8->

Sign In or Register to comment.