How do i make this tree properly scale?

edited October 2016 in Questions about Code

Hi, I've been working on this beginner-level class in processing. This one is a class for a tree I'm trying to make, but I'm running into some trouble. As you can probably see in my code, I've been trying to make an option to scale the trees, and it's half working and half not-working. The objects (rect, ellipse) scales well, but the position doesn't scale with it, and I can't seem to find the solution to it.

So my question is, how do I scale this by entering data in the constructor, while keeping its proportion?

class Tree {

float xposTree;
float yposTree;
float sizeTree;


Tree(float tempXposTree, float tempYposTree, float tempSizeTree) {
xposTree = tempXposTree;
yposTree = tempYposTree;
sizeTree = tempSizeTree;
}

void display() {
  noStroke();
  fill(160,82,45);
  rect(xposTree,yposTree-50,10*sizeTree,50*sizeTree); //The trunk
  fill(34,139,34);
  ellipse(xposTree+5, yposTree-50, 25*sizeTree, 25*sizeTree); //Middle ellipse
  ellipse(xposTree-7.5,yposTree-50,25*sizeTree,25*sizeTree); //Left ellipse
  ellipse(xposTree+17.5,yposTree-50,25*sizeTree,25*sizeTree); //Right ellipse
  ellipse(xposTree+5,yposTree-62.5,25*sizeTree,25*sizeTree); //Top ellipse
}
}

Tree myTree1;

void setup() {
size(1000,300);
myTree1 = new Tree(100,100,1);
}

void draw() {
background(255);
myTree1.display();
}
Tagged:

Answers

  • I think you should treat those two things differently. Why would your position change if you changed the size?

    You've already got parameters for the position, why don't you just use that?

    What exact behavior are you looking for?

  • Answer ✓

    This shows how to do it flowers. It uses a number of statements

    pushMatrix & popMatrix to isolate transformstion so each flower can be drawn without knowing where the others are

    translate() moved the drawing origin for the flower to simplify the drawing commands

    scale() simply scale the drawing surface

    class Flower {
      float px;
      float py;
      float sf;
    
      Flower(float x, float y, float s) {
        px = x;
        py = y;
        sf = s;
      }
    
      void display() {
        pushMatrix();
        // Move the drawing origin to [px, py]
        translate(px, py);
        // Now scale the canvas
        scale(sf);
        // draw the flower
        noStroke();
        fill(200, 82, 45);
        // The stem
        rect(-5, 0, 10, 80);
        fill(160, 20, 0);
        // The petals
        ellipse(-20, -20, 50, 50); 
        ellipse( 20, 20, 50, 50); 
        ellipse(-20, 20, 50, 50); 
        ellipse( 20, -20, 50, 50);
        // the centre
        fill(255, 240, 0);
        ellipse(0, 0, 30, 30);
        popMatrix();
      }
    }
    
    Flower f0, f1, f2, f3;
    
    void setup() {
      size(1000, 300);
      f0 = new Flower(100, 200, 0.5);
      f1 = new Flower(300, 180, 1);
      f2 = new Flower(500, 150, 1.5);
      f3 = new Flower(700, 130, 2);
    }
    
    void draw() {
      background(255);
      f0.display();
      f1.display();
      f2.display();
      f3.display();
    }
    
  • edited October 2016

    @KevinWorkman, What I'm trying to do, or trying to fix rather: When I enter a size value in my constructor, I want it to scale the tree to that value.

    When I enter the value 1 it looks normal, since multiplying by 1 doesn't change anything. (https://gyazo.com/4748027fd7dda3cf3e446cef4e182b7f

    When I enter a value like 2 or 0,5, that's where I start getting some trouble.

    0,5: (https://gyazo.com/3b3d06c0edecd5a7860903597963024d

    2: https://gyazo.com/7eb2d6aa88e67dd57b3fab0dd3cc6bb2

    The objects scale like they're supposed to, but as they become bigger/smaller, they'd need new x and y values, since they're either overlapping or not reaching each other now.

    And that's my question; How I make them stay with the same amount of overlapping, when I scale it to be bigger/smaller.

    I hope that explained it a little better :-)

    Edit: Seemed like the pictures weren't showing properly, so now they're just links.

  • I see. You're talking about the positions of the sub-objects of the tree, not of the overall tree itself.

    You're going to need to break your problem down into smaller steps. If I were you, I'd break out some graph paper and draw some examples to help you visualize how to draw things.

    Decide what the "origin" of the tree should be: maybe the bottom of the trunk? Or its top? Or maybe the top-left corner of the whole tree? Once you have that coordinate and a size, then you have to figure out where to draw everything else in relation to that size. That's where the graph paper comes in handy.

    Take your tree parts one at a time: can you get just the trunk showing up with the correct size?

    Once you have that working, then add a single green circle part. Get that working, then add another green part, etc.

  • These absolute arguments like "-50" etc. won't work. For a tree 100 wide, no big deal. Now imagine a tree 5 pixels wide. When you move a part of the tree 50 away, what happens? That's really far. all your arguments should be relative -- expressed as proportions of your base size arguments -- like "move the left green branch half-a-trunk-width over" is expressed as -treeWidth*0.5

    I think your approach of giving a size to your Tree objects is fundamentally correct, but there is also an alternate approach (with its own drawbacks). That is to have every tree always be the same size, but wrap them in a scale call to draw them at different sizes:

    pushMatrix();
      scale(4);
      myTree.display();
    popMatrix();
    
  • edited October 2016

    Have you tried the code I posted above because it seems to solve the problem? If not say why not then we can try again.

  • @quark I just got home a couple of hours ago, and haven't really had the chance to look at it yet, but after running the code I can confirm that this is what I'm looking for, I will just have to insert my data into this form.

    I'll return to you once I've (hopefully) been able to do that^^ :-)

Sign In or Register to comment.