Loading...
Logo
Processing Forum
I am writing a program that records user input for the location of two axes of what will become a graph. Once distances from the edge of the window are set, I want the program to create a ratio that will allow the window to be resized so that when it is, the axes are still the same relative distance away from the window borders. If that statement isn't clear enough, I want the user to place (for example) the graph's y axis in the desired location. Then, if the user decreases the width of the window by 50%, the distance between the window's edge and the y axis also decreases by 50% rather than there being a constant difference of space between them (i.e. 32 pixels, or something like that).

I thought that that would be a fairly simple thing to do, but I have been running into problems with, what I assume, is Processing rounding the numbers I need for the ratio to zero. Unless I have made some coding mistake that I missed, the numbers (only two decimal places) put out by the simple line of division always end up being zero.

There is the code, as it stands, in my sketch right now. Although some of it may not make sense, I was doing a bunch of commenting-out for debugging purposes. The only area of interest relative to this problem (I think) is the highlighted region, but I included all of the code so that it's in-context.

Thanks!
~J

Copy code
  1. //Initialize variables
    PFont font;
    int xofy, yofx; //x-cor of y axis, y-cor of x axis
    float xrat, yrat; //ratio of difference between window width and x-cor of y axis to window width, ratio of difference between window height and y-cor of x axis to window height
    boolean clicked = false;
    boolean done = false;
    void setup() {
      size(800, 500);
      frame.setResizable(true);
      font = loadFont("CourierNewPSMT-16.vlw");
      //font = createFont("CourierNewPSMT", 16, true);
    }
    void draw() {
      //Set up to draw lines and write text
      background(0);
      fill(255);
      stroke(255);
      textFont(font, 16);
      textAlign(CENTER, CENTER); /*
      if(!(done)) { //If selections have not been made
        if (clicked) { //If the user has already aligned the y axis
          line(xofy, 0, xofy, mouseY); //Draw a line from the top of the window to the mouse's y-cor along the selected x-cor value
          line(xofy, mouseY, width, mouseY); //Draw a line from the bottom left corner where the already selected x-cor meets the mouse's y-cor
          if (yofx!=0) { //If the mouse has not been clicked a second time
            text(width+" pixels by "+height+" pixels are the window dimensions\nx: "+mouseX+" "+xofy+"\ny: "+(height-mouseY)+" "+yofx, width/2, (height/2)-75);
          } else {
            text(width+" pixels by "+height+" pixels are the window dimensions\nx: "+mouseX+" "+xofy+"\ny: "+(height-mouseY)+" "+(height-mouseY), width/2, (height/2)-75);
          }
      } else { //If the mouse has not been clicked
          line(mouseX, height/2, width, height/2); //Draw a line from the mouse's x-cor to the edge of te window along the center of the window horizontally
          line(mouseX, 0, mouseX, height); //Draw a line to the top and bottom of the screen in line with the mouse's x-cor
          if (yofx!=0) { //If the mouse has not been clicked a second time
            text(width+" pixels by "+height+" pixels are the window dimensions\nx: "+mouseX+" "+mouseX+"\ny: "+(height-mouseY)+" "+yofx, width/2, (height/2)-75);
          } else {
            text(width+" pixels by "+height+" pixels are the window dimensions\nx: "+mouseX+" "+mouseX+"\ny: "+(height-mouseY)+" "+(height-mouseY), width/2, (height/2)-75);
          }
        }
      } else { *///If the selections for both axes have been made
        xofy = 40;
        yofx = height-25;
        frame.setResizable(false); //Temporarily, the user can no longer resize the window
        //line(xofy, yofx, xofy, 0); //Both axes with their finalized points are made
        //line(xofy, yofx, width, yofx);
        text("Your lines are "+xofy+" pixels from the left window border\nand "+(height-yofx)+" pixels away from the bottom window border.\nThe window is "+width+" pixels by "+height+" pixels.\nClick anywhere to continue.", width/2, height/2);
        xrat = (height-yofx)/height; //Ratio of distance between window's edge and y axis to height
        yrat = xofy/width; //Ratio of distance between window's edge and x axis to height
        //println(xrat+" "+yrat);
        /*line(yrat*width, abs((xrat*height)-((1-xrat)*height)), yrat*width, 0);
        line(yrat*width, abs((xrat*height)-((1-xrat)*height)), width, abs((xrat*height)-((1-xrat)*height)));*/
       
      }
    //}
    void mouseClicked() {
      if (!(done)) {
        if (clicked) {
          yofx = mouseY;
          done = true;
          clicked = false;
        } else {
          xofy = mouseX;
          clicked = true;
        }
      } else {
        //Do nothing
      }
    }

Replies(15)

integer division problem? add  a println that shows the variables and results in these lines, see if it's what you expect:

xrat = (height-yofx)/height

yrat = xofy/width
Sorry if I hadn't made it clear, but I have already done that. I did debugging and isolated the problem. It appeared to have started when I initially assigned that value to those variables, because the output was always 0.0 for both of them. That's why I assumed that it was a rounding issue.

~J

EDIT: I tried the println thing again, same issue.

DOUBLE EDIT: I tried this:

Copy code
  1. xrat = (500-(500-25))/500;
  2. yrat = 40/800;
and replaced the variables with their literal default values, and it returned the same error. I'm not sure if this is significant, other than proving that it doesn't matter whether or no I have "height" and "width" for there to be an error.
I think it's because width and height change when resizing and because width and height are whole numbers there will be rounding errors.


void setup(){
  size(500,500);
  frame.setResizable(true);
  background(0);
}

void draw(){
  background(0);
  println("Width: " + width + " Height: " + height);
}
Thanks for the reply, but I'm not so sure. It's not so much rounding errors as it is that it's being rounded to zero every time, and I cannot make a ratio with zero. As you can see, I already have the program outputting the width and height of the screen (although it's been commented out), and there have been no issues with it. I'll try converting the width and height to a float data type when they are assigned to xrat and yrat, but I'm not convinced it will make much of a difference because the height and width being whole numbers hasn't really caused problems for me before.

~J
Nevermind, it was an issue with not all of them being floats. I'm working on fixing it now, but by converting some of them to floating point numbers, it seems to have solved the problem to some degree.

Thanks!
~J
Have You tried this?

  float  xrat = (500-(500-25))/500;
  float  yrat = 40/800;
  float  x2rat = (500-(500-25))/500.0f; // divide explicitly by a float
  float  y2rat = 40/800.0f;             // divide explicitly by a float
  println("xrat: " + xrat + " yrat: " + yrat + " x2rat: " + x2rat + " y2rat: " + y2rat);
Yes, that was the second reply to your comment, I was saying that it worked. Here's the updated code:

Copy code
  1. //Initialize variables
    PFont font;
    int xofy, yofx; //x-cor of y axis, y-cor of x axis
    float xrat, yrat; //ratio of difference between window width and x-cor of y axis to window width, ratio of difference between window height and y-cor of x axis to window height
    boolean clicked = false;
    boolean done = false;
    void setup() {
      size(800, 500);
      frame.setResizable(true);
      font = loadFont("CourierNewPSMT-16.vlw");
      //font = createFont("CourierNewPSMT", 16, true);
    }
    void draw() {
      //Set up to draw lines and write text
      background(0);
      fill(255);
      stroke(255);
      textFont(font, 16);
      textAlign(CENTER, CENTER);
      if(!(done)) { //If selections have not been made
        if (clicked) { //If the user has already aligned the y axis
          line(xofy, 0, xofy, mouseY); //Draw a line from the top of the window to the mouse's y-cor along the selected x-cor value
          line(xofy, mouseY, width, mouseY); //Draw a line from the bottom left corner where the already selected x-cor meets the mouse's y-cor
          if (yofx!=0) { //If the mouse has not been clicked a second time
            text(width+" pixels by "+height+" pixels are the window dimensions\nx: "+mouseX+" "+xofy+"\ny: "+(height-mouseY)+" "+yofx, width/2, (height/2)-75);
          } else {
            text(width+" pixels by "+height+" pixels are the window dimensions\nx: "+mouseX+" "+xofy+"\ny: "+(height-mouseY)+" "+(height-mouseY), width/2, (height/2)-75);
          }
      } else { //If the mouse has not been clicked
          line(mouseX, height/2, width, height/2); //Draw a line from the mouse's x-cor to the edge of te window along the center of the window horizontally
          line(mouseX, 0, mouseX, height); //Draw a line to the top and bottom of the screen in line with the mouse's x-cor
          if (yofx!=0) { //If the mouse has not been clicked a second time
            text(width+" pixels by "+height+" pixels are the window dimensions\nx: "+mouseX+" "+mouseX+"\ny: "+(height-mouseY)+" "+yofx, width/2, (height/2)-75);
          } else {
            text(width+" pixels by "+height+" pixels are the window dimensions\nx: "+mouseX+" "+mouseX+"\ny: "+(height-mouseY)+" "+(height-mouseY), width/2, (height/2)-75);
          }
        }
      } else { //If the selections for both axes have been made
        //frame.setResizable(false); //Temporarily, the user can no longer resize the window
        //line(xofy, yofx, xofy, 0); //Both axes with their finalized points are made
        //line(xofy, yofx, width, yofx);
        text("Your lines are "+xofy+" pixels from the left window border\nand "+(height-yofx)+" pixels away from the bottom window border.\nThe window is "+width+" pixels by "+height+" pixels.\nClick anywhere to continue.", width/2, height/2);
        xrat = (float)((float)height-(float)yofx)/(float)height; //Ratio of distance between window's edge and y axis to height
        yrat = (float)((float)xofy/(float)width); //Ratio of distance between window's edge and x axis to height
        xofy = (int) (yrat*width); //Apply the ratio to the window size to draw the axes
        yofx = (int) ((1-xrat)*height); //Apply the ratio to the window size to draw the axes
        line(xofy, yofx, xofy, 0);
        line(xofy, yofx, width, yofx);
        int f = 0;
        if (f < 100) {
          println(f);
          f++;
        }
      }
    }
    void mouseClicked() {
      if (!(done)) {
        if (clicked) {
          yofx = mouseY;
          done = true;
          clicked = false;
        } else {
          xofy = mouseX;
          clicked = true;
        }
      } else {
        //Under construction
      }
    }
I set up the thing with the variable "f" just to test it because it has been acting weird. The float thing worked (although I did it a little differently than you) but something is still acting up, and it's not updating the axes when I change the window size, even though it's supposed to. Does that have anything to do with my solution to the previous problem?

Thanks,
~J
For the record, it is a common problem addressed in the Troubleshooting part of the wiki.

A little late, but thanks. I wasn't even aware that there is a Processing wiki. It might be beneficial to make it easier to access from the Processing website, because I could have used that page in many different situations so far today, but I wasn't able to find it.

~J
and that's exactly what i meant by 'integer division problem' 8)
Sorry, for some reason I was being extremely counter-intuitive. Still, thanks for the hint that was too subtle for me.
And that's why I show the info about the wiki entry, even if it is late: to highlight the existence of the wiki (don't forget the Technical FAQ too!) and to be of benefit to people exploring / searching the forum.
Hi PhiLho and jstrieb,
I too think that we don't have to reenvent the wheel twice. And so I find it is important to point people to resources that allready exist  like you do PhiLho. I myself learnt a lot from people on forums, when I was a new bee. I still am, I guess. But sometimes I think it is useful to get a short answer that doesn't need to follow links as a short descriptive example. Processing is a great platform for creative people and I appreciate it very much how people help eachother.  When I posted an other example of coercion of a number to a float I didn't mean to bother you jstrieb. I just thought it would be helpfull to to see another method of coercion. So stay tuned I appreciate it very much.
Peter
You were no bother at all, I just misunderstood your intentions. I appreciate the help. Since the conception of this thread, I have progressed considerably in the code, partly thanks to the reuse and recycling of that which was provided to me by PhiLho and yourself, so thank you, and thank you, too, PhiLho.

~J
OK, thank you