Loading...
Logo
Processing Forum

noob question

in Programming Questions  •  6 months ago  
hey guys

i hope someone can help me with this tiny piece of code.

my aim is to draw an ellipse at middle of the screen, trace a oblique line between the border of the canvas and the ellipse and then repeat the process by drawing another ellipse a bit further and tracing another oblique line...

this is my code until now.. can u tell me what am i doing wrong?

Copy code
  1. int destX, destY, h, point_x, point_y;


  2. void setup(){
  3.   
  4.   size (200,200);
  5.   
  6.   destX = width/2;
  7.   destY = height/2;
  8.   
  9.   h = height - destY;
  10.   point_x = destX - h;
  11.   point_y = height;
  12.   
  13.   frameRate(20);
  14.   
  15. }

  16. void draw (){
  17.   fill(0);
  18.   
  19.   for (int x=width/2; x<width; x=x+7){
  20.     ellipse(x, height/2, 4,4);
  21.   }
  22.  
  23.   ellipse(point_x, point_y, 4,4);
  24.   point_x++;
  25.   point_y--;

  26. }

Replies(11)

Re: noob question

6 months ago
This is what I've come up with:
Copy code
    int dimX, dimY, centerX, centerY, pointX, pointY;
    final static byte   INC = 10, BOLD = 3, FPS = 100;
    final static color  BG = 0350, FG = #4060A0, BRUSH = #FFFF00;
    final static String ENGINE = P2D; // Use JAVA2D for Processing 2+
    
    void setup() {
      size(200, 200, ENGINE);
      frameRate(FPS);
      strokeWeight(BOLD);
    
      dimX = centerX = width>>1;
      dimY = centerY = height>>1;
    }
    
    void draw () {
      point(pointX++, pointY--);
      if (pointX > width | pointY < 0)  reposition();
    }
    
    void reposition() {
      pointX = centerX - height + centerY;
      pointY = height;
    
      background(BG);
      noStroke();
      fill(BRUSH);
    
      ellipse(centerX, centerY, dimX, dimY);
    
      stroke(FG);
    
      centerX += INC;
      centerY += INC;
    
      if (centerX > width & centerY > height)
        centerX = centerY = 0;
    }
    

Re: Re: noob question

6 months ago
thank u very much GoToLoop!

i'll just make two more questions:
Copy code
  1. dimX = centerX = width>>1;
what does this 'width>>1' means?

Copy code
  1. if (pointX > width | pointY < 0)
having the ' | ' is like having ' | | ' right?

despite the code is written in a way that i'm not used to, i guess i was able to achieve the thing that i wanted. thank u so much. here is the thing that i wanted. 

Copy code
  1. int dimX, dimY, centerX, centerY, pointX, pointY;

  2. final static byte   INC = 10, BOLD = 3, FPS = 100;
  3. final static color  BG = 0350, FG = #4060A0, BRUSH = #FFFF00;
  4. final static String ENGINE = P2D; // Use JAVA2D for Processing 2+

  5. void setup() {
  6.   size(200, 200, ENGINE);
  7.   frameRate(FPS);
  8.   strokeWeight(BOLD);

  9.   dimX = centerX = width>>1;
  10.   dimY = centerY = height>>1;
  11. }

  12. void draw () {
  13.   point(pointX++, pointY--);
  14.   if (pointX > width | pointY < height/2)  reposition();
  15. }

  16. void reposition() {
  17.   pointX = centerX - height + centerY;
  18.   pointY = height;

  19.   //background(BG);
  20.   noStroke();
  21.   fill(BRUSH);

  22.   ellipse(centerX, centerY, 5, 5);

  23.   stroke(FG);
  24.   
  25.   centerX += INC;
  26.     
  27.   if (centerX > width)
  28.     centerX = centerY = width/2;
  29.   
  30. }

Re: noob question

6 months ago
     dimX = centerX = width>>1; is a bit shift.

for example 


    int a = 5;        // binary: 0000000000000101
    int b = a << 3;   // binary: 0000000000101000, or 40 in decimal
    int c = b >> 3;   // binary: 0000000000000101, or back to 5 like we started with

Re: noob question

6 months ago
Yes, GoToLoop likes to show off and confuse newbies with special tricks... (or just has his own special style of programming, to be kinder...)

width >> 1 is just width / 2
if (pointX > width | pointY < 0) is an inefficient equivalence to if (pointX > width || pointY < 0)
Inefficient because the version with || stops if the first test is true, while the version with | must check both tests.

BTW, pedroam, please, try and use better subject lines. As you can see in the URL, the subject was numbered because it is not unique! The line is unhelpful, not telling what is your exact problem. Imagine a forum where each topic is named "help me", "noob aboard", "please help me asap", etc.
Lot of people around are indeed newbies, and you are in the Programming Questions section, so we expect you to ask a question...
Something like "draw ellipses and oblique lines" (straight from your first message) would be more explicit.
It is easier to find back a topic when it has a unique and explicit subject.

Re: noob question

6 months ago
thank you guys!

i'll follow your tips from now on PhiLho.


Re: noob question

6 months ago

Inefficient because the version with || stops if the first test is true, while the version with | must check both tests.
That is true indeed. But in order to do that, there has to be a little overhead to create a code branch check for it!
Lazy evaluations are more complex than eager ones. In fact, bitwise operators are faster than other types!

For simple expressions, it's faster to evaluate each 1 of them, rather than setup a lazy branch check for each 1;
in hopes to get a short-circuiting outta 'em at some point!

Of course, if there's some operand which is a method call or a heavy calculation, we should always re-arrange the expression
as such that fast tests happen 1st, and those heavy ones can be avoided by short-circuit!

Re: noob question

6 months ago
Here's a quick test I've made. Java is so good at optimizing that any gains are very insignificant! 
Nevertheless, it's still possible to verify that for expressions formed by simpler operands,
eager are faster than lazy! 
Copy code
    final static int ITERATIONS = 20000000, RAND = 10000;
    
    void setup() {
      eagerTest(ITERATIONS >> 4);   // warm-ups
      lazyTest(ITERATIONS  >> 4);
    
      int timer = millis();
      println( eagerTest(ITERATIONS) ); // real eager test
      println( "Eager: " + (millis() - timer) );
    
      timer = millis();
      println( lazyTest(ITERATIONS) );  // real lazy test
      println( "Lazy: " + (millis() - timer) );
    
      exit();
    }
    
    int eagerTest(int ii) {
      float a, b, c, d, e, f, g, h;
      int counter = 0;
    
      for (int i = ii; i != 0; --i) {
        a = random(RAND);
        b = random(RAND);
        c = random(RAND);
        d = random(RAND);
        e = random(RAND);
        f = random(RAND);
        g = random(RAND);
        h = random(RAND);
    
        if (a < b & c > b | e == f & g != h)  ++counter;
      }
    
      return counter;
    }
    
    int lazyTest(int ii) {
      float a, b, c, d, e, f, g, h;
      int counter = 0;
    
      for (int i = ii; i != 0; --i) {
        a = random(RAND);
        b = random(RAND);
        c = random(RAND);
        d = random(RAND);
        e = random(RAND);
        f = random(RAND);
        g = random(RAND);
        h = random(RAND);
    
        if (a < b && c > b || e == f && g != h)  ++counter;
      }
    
      return counter;
    }
    

Re: noob question

6 months ago
" any gains are very insignificant!"
That's why you should drop your funny but useless and confusing optimizations: this is not C, even less assembly language.
In Java, general advice is to write in a readable way, for you and for the others, and to rely on the compiler to do the best optimizations. As the saying goes, optimize only when your program is too slow (or too memory hungry), "premature optimization is the root of all evil". (a slight exaggeration! )

Speed gain given by >> 1, | or usage of final / byte over int and such are generally void in a normal sketch, and you often get confused remarks by newbies looking at these odd constructs.
You are a valuable contributor, that's why I give this advice. Of course, you can ignore it, you are free, but it is too bad you reduce the interest of your good code with these distracting gimmicks.

You know when to use | vs. || for example (in a test like if (x != null && x.length() > 0), using & would be a disaster!), but most newbies would fall in the trap.
Likewise, using byte for a single variable isn't useful (can even be slower than a int!) in terms of memory gain, and some newbies might try to use them beyond 127.
And so on.

Just a friendly advice.

PS.: I forgot about the lazy vs. eager speed difference, your test is interesting.
But I was thinking in more general terms, where expressions are generally complex (eg. rect / rect intersections with intermediary computations, or method calls in the test). If you have to think ahead "is my test simple enough that a bitwise operator will be faster?", you just loose time and energy better spent on general program design.

Re: noob question

6 months ago
although this maybe the wrong place to continue this discussion, i want to add something.

when running the eager/lazy test i get the following results, using randomSeed(2) to make the test fair.

3336402
Eager: 6015
3336402
Lazy: 5938

... so on my machine the lazy test, using the boolean ops, is a bit faster.


But the thing i actually want to point out is:
AFAIK bitwise operators in java work only on integer. So the result of a bitwise operation is an integer, and the operands are too.
This is interesting when looking closer at this line:

if (a < b & c > b | e == f & g != h)  ++counter;

a < b ... boolean
(a < b) & (c > b) ... two boolean operands and bitwise operator.

in that case the two boolean operands have to return an integer for the bitwise
operation to work properly.

when viewing the .class file with a java decompiler (i used http://java.decompiler.free.fr ) the line looks as follows:

if (((a < b ? 1 : 0) & (c > b ? 1 : 0) | (e == f ? 1 : 0) & (g != h ? 1 : 0)) != 0) counter++;


while the line using just boolean ops looks like this:

if (((a < b) && (c > b)) || ((e == f) && (g != h))) counter++;



Re: noob question

6 months ago
Interesting. So the bitwise operator used on booleans actually converts these booleans to integer in order to operate. I didn't know that.

Last note: this kind of "optimizations" are also heavily depending on the used version of Java. It can be a Sun JVM, an Oracle one, an IBM one, an Apple one or an OpenJDK one, to mention but a few. And within these variants, there are version numbers.
All this to say that perhaps an optimization works in a version, and might be void in another. Some old tricks (using final, for example) are probably obsolete since a long time. And so on.
I fear there is no true recipe for speed, except avoiding the usual traps (like using the + concatenation operator to create a long string in a loop).

Re: noob question

6 months ago
Lazy faster here as well :

All with seed(2)

1st run:
3336402
Eager: 2747
3336402
Lazy: 2711


2nd run:
3336402
Eager: 2754
3336402
Lazy: 2695

3rd run:
3336402
Eager: 2770
3336402
Lazy: 2696