//RGBCircles.java import java.awt.*; import java.awt.event.*; import javax.swing.*; public class RGBCircles extends JApplet { private Color color1; //Green circle private Color color2; //Blue circle private Color color3; //Red circle private int appletSize; private int length; //2*b length of private double b; //radius of circles private int x1, y1, x2, y2, x3, y3; //centers of Green, Blue, Red circles public void init() { // color1 = Color.GREEN; // color2 = Color.BLUE; // color3 = Color.RED; color1 = new Color(0,127,0); color2 = new Color(0,0,127); color3 = new Color(127,0,0); addMouseListener( //anonymous inner class overrides mouseClicked new MouseAdapter() { public void mouseClicked( MouseEvent event) { int colorStep = 10; calcSizes(); int x = event.getX(); int y = event.getY(); if (xy1) { //in green if (event.isMetaDown()) //right mouse button if (color1.getGreen() >= colorStep) color1 = new Color( 0, color1.getGreen()-colorStep, 0); else color1 = new Color( 0, 0, 0); else //left button if (color1.getGreen() < 255-colorStep) color1 = new Color( 0, color1.getGreen()+colorStep, 0); else color1 = new Color( 0, 255, 0); } else if (x>x2 && y>y2) { //in blue if (event.isMetaDown()) //right mouse button if (color2.getBlue() >= colorStep) color2 = new Color( 0, 0, color2.getBlue()-colorStep); else color2 = new Color( 0, 0, 0); else if (color2.getBlue() < 255-colorStep) color2 = new Color( 0, 0, color2.getBlue()+colorStep); else color2 = new Color( 0, 0, 255); } else if ( y= colorStep) color3 = new Color( color3.getRed()-colorStep, 0, 0); else color3 = new Color( 0, 0, 0); else if (color3.getRed() < 255-colorStep) color3 = new Color( color3.getRed()+colorStep, 0, 0); else color3 = new Color( 255, 0, 0); } repaint(); } } ); } private void calcSizes() { appletSize = Math.min(getWidth(), getHeight()); //distance between centers is appletSize/3 b = appletSize / 3; //b is radius length = (int)(2 * b); //radii extend to center of other circles x1 = appletSize / 3; y1 = appletSize / 3 * 2; x2 = appletSize / 3 * 2; y2 = appletSize / 3 * 2; double angle = Math.toRadians(60); //top (red) circle's center x3 = (int)(Math.cos(-angle) * appletSize/3 + x1); y3 = (int)(Math.sin(-angle) * appletSize/3 + y1); } public void paint( Graphics g1 ) { super.paint( g1 ); //try 2d graphics. will be used for rotation... Graphics2D g = (Graphics2D) g1 ; double angle; showStatus( "click left mouse for +, right mouse for - of color" ); calcSizes(); //so height of equliateral triangle is double height = Math.sqrt(b*b-b*b/4); //this interferes with drawings: //getContentPane().setBackground( new Color( color3.getRed(), color1.getGreen(),color2.getBlue() ) ); g.setColor( new Color( color3.getRed(), color1.getGreen(), color2.getBlue() )); g.fillRect( 0, 0, getWidth(), getHeight() ); g.setColor( color1 ); //lower left Green g.fillOval(x1-length/2,y1-length/2,length,length); //g.drawOval(x1-length/2,y1-length/2,length,length); g.setColor( color2 ); //lower right Blue g.fillOval(x2-length/2,y2-length/2,length,length); //g.drawOval(x2-length/2,y2-length/2,length,length); g.setColor( color3 ); //top Red g.fillOval(x3-length/2,y3-length/2,length,length); //g.drawOval(x3-length/2,y3-length/2,length,length); //from center, bisect triangle to outer intersection angle = Math.toRadians(30); int red_blue_x = (int)(Math.cos(-angle) * 2*height + x1); int red_blue_y = (int)(Math.sin(-angle) * 2*height + y1); angle = Math.toRadians(150); int red_green_x = (int)(Math.cos(-angle) * 2*height + x2); int red_green_y = (int)(Math.sin(-angle) * 2*height + y2); angle = Math.toRadians(270); int green_blue_x = (int)(Math.cos(-angle) * 2*height + x3); int green_blue_y = (int)(Math.sin(-angle) * 2*height + y3); //upper half of red blue g.setColor( new Color( color3.getRed(), 0, color2.getBlue() ) ); g.translate( x1, y1 ); //move origin g.rotate( -Math.PI / 6 ); //-30 degrees rotation //g.fillArc( x1, (int)(y1-.5*b), (int)(2*height), (int)b, 0, 180 ); g.fillArc( 0, (int)(-.5*b), (int)(2*height), (int)b, 0, 90 ); g.rotate( Math.PI / 6 ); //back to original g.translate( -x1, -y1 ); //back to original //lower half of red blue g.translate( red_blue_x, red_blue_y ); //move origin g.rotate( 5 * Math.PI / 6 ); //150 degrees rotation g.fillArc( 0, (int)(-.5*b), (int)(2*height), (int)b, 90, 180 ); g.rotate( -5 * Math.PI / 6 ); //back to original g.translate( -red_blue_x, -red_blue_y ); //move origin //upper half of red green g.setColor( new Color( color3.getRed(), color1.getGreen(), 0 ) ); g.translate( red_green_x, red_green_y ); //move origin g.rotate( Math.PI / 6 ); //30 degrees rotation g.fillArc( 0, (int)(-.5*b), (int)(2*height), (int)b, 90, 180 ); g.rotate( -Math.PI / 6 ); //back to original g.translate( -red_green_x, -red_green_y ); //move origin //lower half of red green g.translate( x2, y2 ); //move origin g.rotate( 7 * Math.PI / 6 ); //210 degrees rotation g.fillArc( 0, (int)(-.5*b), (int)(2*height), (int)b, 0, 90 ); g.rotate( -7 * Math.PI / 6 ); //back to original g.translate( -x2, -y2 ); //move origin //left half of blue green g.setColor( new Color( 0, color1.getGreen(), color2.getBlue() ) ); g.translate( green_blue_x, green_blue_y ); //move origin g.rotate( 9 * Math.PI / 6 ); //270 degrees rotation g.fillArc( 0, (int)(-.5*b), (int)(2*height), (int)b, 90, 180 ); g.rotate( -9 * Math.PI / 6 ); //back to original g.translate( -green_blue_x, -green_blue_y ); //move origin //right half of blue green g.translate( x3, y3 ); //move origin to center of Red g.rotate( 3 * Math.PI / 6 ); //90 degrees rotation g.fillArc( 0, (int)(-.5*b), (int)(2*height), (int)b, 0, 90 ); g.rotate( -3 * Math.PI / 6 ); //back to original g.translate( -x3, -y3 ); //move origin /* //draw the circles again for visualization debug g.setColor( color2 ); g.drawOval(x1-length/2,y1-length/2,length,length); g.setColor( color3 ); g.drawOval(x2-length/2,y2-length/2,length,length); g.setColor( color1); g.drawOval(x3-length/2,y3-length/2,length,length); */ //inner triangle g.setColor( new Color( color3.getRed(), color1.getGreen(), color2.getBlue() )); g.fillPolygon( new int[]{x1-1,x2,x3-1}, new int[]{y1,y2,y3-1}, 3); //-1 tweaks to reduce background line peeking thru /* //draw triangle for visualization debug g.setColor( Color.BLACK ); g.drawLine(x1,y1,x2,y2); //lower g.setColor( Color.WHITE ); g.drawLine((x1+x2)/2,(y1+y2)/2,(x1+x2)/2,(y1+y2)/2); g.setColor( Color.BLACK ); g.drawLine(x1,y1,x3,y3); g.setColor( Color.WHITE ); g.drawLine((x1+x3)/2,(y1+y3)/2,(x1+x3)/2,(y1+y3)/2); g.setColor( Color.BLACK ); g.drawLine(x2,y2,x3,y3); g.setColor( Color.WHITE ); g.drawLine((x3+x2)/2,(y3+y2)/2,(x3+x2)/2,(y3+y2)/2); */ /* //from center, bisect triangle to outer intersection g.setColor( Color.WHITE ); g.drawLine(x1,y1, red_blue_x, red_blue_y); g.drawLine(x2,y2, red_green_x, red_green_y); g.drawLine(x3,y3, green_blue_x, green_blue_y); */ g.setFont( new Font( "SansSerif", Font.BOLD, 20 ) ); g.drawString( ""+color1.getGreen(), (int)(x1-.5*b), (int)(y1+.5*b) ); g.drawString( ""+color2.getBlue(), (int)(x2+.5*b), (int)(y2+.5*b) ); g.drawString( ""+color3.getRed(), (int)(x3), (int)(y3-.5*b) ); } }