why is the result so different in 2.1

edited November 2013 in Using Processing

can someone run this code in 2.0.3 and then in 2.1

Press the mouse at a few different places.

import java.util.*;

float centerX, centerY;

ArrayList<Tangible> tangibles = new ArrayList<Tangible>();

void setup() {
  size(700, 700); 
  smooth();
  frameRate(60);

  centerX = width/2;
  centerY = height/2;
}

// . . . . . . . . . . . . . . . . . . .


void draw() {
  background(0);

  fill(255);
  noStroke();
  ellipse(centerX, centerY, 10, 10);

  for (int i = 0; i < tangibles.size(); i++) {
    Tangible t = tangibles.get(i);
    ellipse(t.centerX, t.centerY, 15, 15);
  }

  synthLineDraw();

  float a = atan2(mouseY-centerY, mouseX - centerX);
  if (a < 0) a += TWO_PI;
  //println(a);
  pushMatrix();
  translate(centerX, centerY);
  rotate(a);
  line(200, 0, 0, 0);
  popMatrix();

  Tangible previous = previousTangibleFromAngle(a);
  Tangible next = nextTangibleFromAngle(a);


  if (previous != null) {
    stroke(255, 0, 0);
    noFill();
    ellipse(previous.centerX, previous.centerY, 25, 25);

    stroke(0, 255, 0);
    noFill();
    ellipse(next.centerX, next.centerY, 25, 25);

    float t; 

    // radius
    float r1, r2;
    float rDifference;

     r1 = dist(previous.centerX, previous.centerY, centerX, centerY);
     r2 = dist(next.centerX, next.centerY, centerX, centerY);
     rDifference = r2 - r1;

     if(previous.angle < next.angle) {
       t = norm(a, previous.angle, next.angle);
     }
     else {
       float angleTillTwoPi = TWO_PI - previous.angle;
       float pa = 0;
       float na = next.angle + angleTillTwoPi;
       float a2;
      if(a >=  previous.angle) {
        a2 = a - previous.angle;
      }
      else {
       a2 = a + angleTillTwoPi; 
      }
      t = norm(a2, pa, na);
     }

    fill(255);
    float y = 20;
    text("a: "+a, 20, y+=20);
    text("t: "+t, 20, y+=20);
    text("r1 (previous): "+r1, 20, y+=20);
    text("r2 (next):"+r2, 20, y+=20);
    text("pervious angle: "+previous.angle, 20, y+=20);
    text("next angle: "+next.angle, 20, y+=20);

    text("rDifference: "+rDifference, 20, y+=20);
    float r = r1 + rDifference * t;

    pushMatrix();
    translate(centerX, centerY);
    rotate(a);
    ellipse(r, 0, 10, 10);
    popMatrix();
  }




  fill(255);
  text(frameRate, 20, height-20);
}

// . . . . . . . . . . . . . . . . . . .

// assumes tangibles are sorted
float interpolatedTangibleRadius(float a, Tangible t1, Tangible t2) {
  return -1;
}

// . . . . . . . . . . . . . . . . . . .

// assumes tangibles are sorted
Tangible previousTangibleFromAngle(float a) {
  if (tangibles.size() > 0) {
    Tangible t = tangibles.get(0);
    if (a < t.angle) {
      // last one in list
      return  tangibles.get(tangibles.size()-1);
    }
    else {

      int index = tangibles.size()-1;

      do {
        t = tangibles.get(index);
        index--;
      }
      while (a < t.angle);

      return t;
    }
  }
  return null;
}


// assumes tangibles are sorted
Tangible nextTangibleFromAngle(float a) {
  if (tangibles.size() > 0) {
    Tangible t = tangibles.get(tangibles.size()-1);
    if (a > t.angle) {
      // last one in list
      return  tangibles.get(0);
    }
    else {

      int index = 0;

      do {
        t = tangibles.get(index);
        index++;
      }
      while (a > t.angle);

      return t;
    }
  }
  return null;
}



// . . . . . . . . . . . . . . . . . . .



void synthLineDraw() {
  stroke(255, 200);

  if (tangibles.size() >= 2) {
    Tangible t1 = null;
    Tangible t2 = null;
    for (int i = 0; i < tangibles.size(); i++) {
      float aDifference;
      if (i == tangibles.size()-1) {
        t1 = tangibles.get(0);
        t2 = tangibles.get(i);

        aDifference = t2.angle - t1.angle - TWO_PI;
      }
      else {
        t1 = tangibles.get(i);
        t2 = tangibles.get(i+1);
        aDifference = t2.angle - t1.angle;
      }

      // radius
      float r1 = dist(t1.centerX, t1.centerY, centerX, centerY);
      float r2 = dist(t2.centerX, t2.centerY, centerX, centerY);

      float rDifference = r2 - r1;

      // the larger the radius the more steps we use
      int steps = (int) max(r1, r2);
      // steps /= 2;

      //println("steps: "+steps);

      // previous
      float px = cos(t1.angle) * r1;
      float py = sin(t1.angle) * r1;


      for (int s = 0; s <= steps; s++) {
        float t = norm(s, 0, steps);
        //float r = map(t, 0, 1, r1, r2);
        float r = r1 + rDifference * t;
        //float a = map(t, 0, 1, t1.angle, t2.angle);
        float a = t1.angle + aDifference * t;
        float x = cos(a) * r;
        float y = sin(a) * r;

        line(px + centerX, py + centerY, x + centerX, y + centerY);
        px = x;
        py = y;
      }
    }
  }
}




boolean mouseDragged;

void mouseDragged() {

  mouseDragged = true;

  Tangible closest = closestTangible(mouseX, mouseY);
  if (closest != null) {
    float d = dist(mouseX, mouseY, closest.centerX, closest.centerY);
    if (d < 40) {
      closest.centerX = mouseX;
      closest.centerY = mouseY;
      closest.calculateAngle(centerX, centerY);
      sortTangibles();
    }
  }
}


// . . . . . . . . . . . . . . . . . . .


void mouseReleased() {

  if (mouseDragged) {
    mouseDragged = false;
    return;
  }

  Tangible closest = closestTangible(mouseX, mouseY);

  if (closest == null) {
    Tangible t = new Tangible(mouseX, mouseY);
    t.calculateAngle(centerX, centerY);
    tangibles.add(t);
  }
  else {
    float d = dist(mouseX, mouseY, closest.centerX, closest.centerY);
    if (d < 20) {
      tangibles.remove(closest);
    }  
    else {
      Tangible t = new Tangible(mouseX, mouseY);
      t.calculateAngle(centerX, centerY);
      tangibles.add(t);
    }
  }

  sortTangibles();
}


// . . . . . . . . . . . . . . . . . . .

void sortTangibles() {
  Collections.sort(tangibles, new TangibleComparator());
  println();
  for (int i = 0; i < tangibles.size(); i++) {
    Tangible t = tangibles.get(i);
    println(t.angle);
  }
}

// . . . . . . . . . . . . . . . . . . .



Tangible closestTangible(float x, float y) {
  Tangible closest = null;
  float closestDist = MAX_FLOAT;

  for (int i = 0; i < tangibles.size(); i++) {
    Tangible t = tangibles.get(i);
    float d = dist(t.centerX, t.centerY, x, y);
    if (d < closestDist) {
      closestDist = d;
      closest = t;
    }
  }

  return closest;
}

// . . . . . . . . . . . . . . . . . . .

class Tangible {

  float centerX, centerY;
  float angle;

  Tangible(float centerX, float centerY) {
    this.centerX = centerX;
    this.centerY = centerY;
  }

  void calculateAngle(float x, float y) {
    angle = atan2(centerY -y, centerX-x);
    //angle = atan2(y-centerY, x-centerX);
    if (angle < 0) angle += TWO_PI;
  }
}

// . . . . . . . . . . . . . . . . . . .

class TangibleComparator implements Comparator<Tangible> {

  int compare(Tangible t1, Tangible t2) {
    if (t1.angle > t2.angle) {
      return 1;
    }  
    else if (t1.angle > t2.angle) {
      return -1;
    }
    return 0;
  }
}

Answers

  • I don't know what is wrong / different and I have no time to try, but have you read the release notes?

  • yes, i always read the release notes. I didn't read anything that could be related. I will dig into it tomorrow some more, to see if it's a processing bug or change.

  • edited November 2013

    Fortunately, I have both versions and checked your code and found no difference in results. Now can you tell us what problem exactly you are encountering ?

  • Yes, playing guess games here isn't really fruitful. Differences can also come from the system you use, some people report differences for MacOS, etc.

  • This is in processing 2.03:

    Screen Shot 2013-11-10 at 3.30.30 PM

    this in 2.1: Screen Shot 2013-11-10 at 3.29.33 PM

    mac os x

  • Tested on Windows 8: At the third click in 2.1 it draws the figure strangely (like in your 2.1 picture).

  • Confirmed, Windows 7. It appears to be a problem not just in the lines drawn, but also in determining the mouse location... perhaps a new bug in the trig functions such as atan2().

  • Note that we switched from Java 6 to Java 7, it might cause some issues (but shouldn't!).

  • Please post the shortest possible piece of code that reveals this issue.

  • OK, now I had time to try, and indeed, there is a big difference between 2.0.0 (stable version) and 2.1 (current one). Now, the 2.1 results are identical to those obtained in 1.5.1, which is a good thing, I think.

    Perhaps there was a bug in 2.0, fixed in 2.1?

  • I got it. I think they changed the sorting method in java. My if and else if where the same. For some reason this was no problem in previous processing (java version).

    class TangibleComparator implements Comparator<Tangible> {
    
      int compare(Tangible t1, Tangible t2) {
        if (t1.angle > t2.angle) {
          return 1;
        }  
        else if (t1.angle **<** t2.angle) {
          return -1;
        }
        return 0;
      }
    }
    
  • edited November 2013

    I've bumped into something similar to it even in Processing 1.5.1, when I had changed from Java 6 to Java 7!!! $-)

    In Java 6, there was no need to return exactly -1, 0, 1. It was permissible of returning any negative or positive values for -1 & 1:

    int compare(Tangible t1, Tangible t2) {
      return (int) (t1.angle - t2.angle);
    }
    

    From now on, it demands Math.signum() of their diff.:

    int compare(Tangible t1, Tangible t2) {
      return (int) Math.signum(t1.angle - t2.angle);
    }
    

    As a side note, I don't get why Processing devs refused/forgotten to include signum() as a sanctioned/canonical API collection!? :-<

Sign In or Register to comment.