Jump to content

Rainbow Mouse Trail


Recommended Posts

Posted (edited)

This is really cool if you want it for your paint. 

LinkedList<MousePathPoint> mousePath = new LinkedList<MousePathPoint>();
    public class MousePathPoint extends Point {

        private long finishTime;
        private double lastingTime;

        public MousePathPoint(int x, int y, int lastingTime) {
            super(x, y);
            this.lastingTime = lastingTime;
            finishTime = System.currentTimeMillis() + lastingTime;
        }

        public boolean isUp() {
            return System.currentTimeMillis() > finishTime;
        }
    }
  public void nextRGB() {
        if ( r == 255 && g < 255 && b == 0 )
        {
            g++;
        }
        if ( g == 255 && r > 0 && b == 0 )
        {
            r--;
        }
        if ( g == 255 && b < 255 && r == 0 )
        {
            b++;
        }
        if ( b == 255 && g > 0 && r == 0 )
        {
            g--;
        }
        if ( b == 255 && r < 255 && g == 0 )
        {
            r++;
        }
        if ( r == 255 && b > 0 && g == 0 )
        {
            b--;
        }
    }
    public Color nextColor() {
        nextRGB();
        return makeColor();
    }
    public Color makeColor()
    {
        return new Color(r, g, b);
    }

Example:

   @Override
    public void onPaint(Graphics2D g) {

    while (!mousePath.isEmpty() && mousePath.peek().isUp())
                    mousePath.remove();
                Point clientCursor = mouse.getPosition();
                MousePathPoint mpp = new MousePathPoint(clientCursor.x, clientCursor.y, 500);
                if (mousePath.isEmpty() || !mousePath.getLast().equals(mpp))
                    mousePath.add(mpp);
                MousePathPoint lastPoint = null;
                for (MousePathPoint a : mousePath) {
                    if (lastPoint != null) {
                        g.setColor(nextColor());
                        g.drawLine(a.x, a.y, lastPoint.x, lastPoint.y);
                    }
                    lastPoint = a;
                }
}
Edited by Dark Magician
  • Like 1
Posted (edited)

You are performing the same check multiple times. For example:

if ( r == 255 && g < 255 && b == 0 ) {
    g++;
}

if ( r == 255 && b > 0 && g == 0 ) {
    b--;
}

You check if r == 255 twice. Consider using if-else statements:

 

if(r == 255) {
    if(g < 255 && b == 0) {
        g++;
    } else if(g == 0 && b > 0) {
        b--;
    }
} else if(r == 0) {
    if(b < 255 && g == 255) {
        b++;
    } else if(b == 255 && g > 0) {
        g--;
    }
} else if(r > 0 && r < 255) {
    if(g == 255 && b == 0) {
        r--;
    } else if(g == 0 && b == 255) {
        r++;
    }
}

Although this helps with the checks, it can still be improved greatly.

 

First, there is a specific time for a specific color to increase and for it to decrease. It's a little easier to understand if you label your conditions:

 

boolean maxRed = r == 255;
boolean noRed = r == 0;
boolean someRed = r > 0 && r < 255;


boolean maxGreen = g == 255;
boolean noGreen = g == 0;
boolean someGreen = g > 0;
boolean notAllGreen = g < 255;


boolean maxBlue = b == 255;
boolean noBlue = b == 0;
boolean someBlue = b > 0;
boolean notAllBlue = b < 255;


if(maxRed) {
    if(notAllGreen && noBlue) {
        g++;
    } else if(noGreen && someBlue) {
        b--;
    }
} else if(noRed) {
    if(notAllBlue && maxGreen) {
        b++;
    } else if(maxBlue && someGreen) {
        g--;
    }
} else if(someRed) {
    if(maxGreen && noBlue) {
        r--;
    } else if(noGreen && maxBlue) {
        r++;
    }
}

So green only increases when there is max red, no blue and notAllGreen (0 to 254 green). It goes down if theres no red, max blue and some green (1 to 255).

 

With that knowledge, and the help of the variables (which could be inlined if wanted), you can use a nested ternary. Although people find nesting ternaries to be abuse (hard to read sometimes), it's a lot easier to understand than what you got going on now:

boolean needsGreen = maxRed && noBlue && notAllGreen;
boolean reduceGreen = noRed && maxBlue && someGreen;

g += needsGreen ? 1 : reduceGreen ? -1 : 0;
b += ...; //do same for blue
r += ...; //do same for red

This code is a victim of the same problem I mentioned before (double checks), but not only is it cleaner, ternaries help avoid branch predictor failures (see this for more info). 

 

I'm gonna be honest, I haven't tested the code I presented, but the philosophy still applies

 

Edited by fixthissite
Posted

 

You are performing the same check multiple times. For example:

if ( r == 255 && g < 255 && b == 0 ) {
    g++;
}

if ( r == 255 && b > 0 && g == 0 ) {
    b--;
}

You check if r == 255 twice. Consider using if-else statements:

 

if(r == 255) {
    if(g < 255 && b == 0) {
        g++;
    } else if(g == 0 && b > 0) {
        b--;
    }
} else if(r == 0) {
    if(b < 255 && g == 255) {
        b++;
    } else if(b == 255 && g > 0) {
        g--;
    }
} else if(r > 0 && r < 255) {
    if(g == 255 && b == 0) {
        r--;
    } else if(g == 0 && b == 255) {
        r++;
    }
}

Although this helps with the checks, it can still be improved greatly.

 

First, there is a specific time for a specific color to increase and for it to decrease. It's a little easier to understand if you label your conditions:

 

boolean maxRed = r == 255;
boolean noRed = r == 0;
boolean someRed = r > 0 && r < 255;


boolean maxGreen = g == 255;
boolean noGreen = g == 0;
boolean someGreen = g > 0;
boolean notAllGreen = g < 255;


boolean maxBlue = b == 255;
boolean noBlue = b == 0;
boolean someBlue = b > 0;
boolean notAllBlue = b < 255;


if(maxRed) {
    if(notAllGreen && noBlue) {
        g++;
    } else if(noGreen && someBlue) {
        b--;
    }
} else if(noRed) {
    if(notAllBlue && maxGreen) {
        b++;
    } else if(maxBlue && someGreen) {
        g--;
    }
} else if(someRed) {
    if(maxGreen && noBlue) {
        r--;
    } else if(noGreen && maxBlue) {
        r++;
    }
}

So green only increases when there is max red, no blue and notAllGreen (0 to 254 green). It goes down if theres no red, max blue and some green (1 to 255).

 

With that knowledge, and the help of the variables (which could be inlined if wanted), you can use a nested ternary. Although people find nesting ternaries to be abuse (hard to read sometimes), it's a lot easier to understand than what you got going on now:

boolean needsGreen = maxRed && noBlue && notAllGreen;
boolean reduceGreen = noRed && maxBlue && someGreen;

g += needsGreen ? 1 : reduceGreen ? -1 : 0;
b += ...; //do same for blue
r += ...; //do same for red

This code is a victim of the same problem I mentioned before (double checks), but not only is it cleaner, ternaries help avoid branch predictor failures (see this for more info). 

 

I'm gonna be honest, I haven't tested the code I presented, but the philosophy still applies

 

 

Thanks for the feedback! The code above works just as presented. 

  • 4 months later...
  • 4 months later...
  • 3 months later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...