// Yoyo - the Yoyodyne Propulsion Systems logo // // Copyright (C) 1996 by Jef Poskanzer . All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // 1. Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // 2. Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF // SUCH DAMAGE. import java.util.*; import java.awt.*; import java.awt.image.*; import java.applet.*; import Acme.Psg; import Acme.PsgException; public class Yoyo extends Applet { // Called when the applet is first created. public void init() { setBackground( Color.white ); } private Psg psg; // Called when the applet should paint itself. public void paint( Graphics graphics ) { try { psg = new Psg( this ); yoyodyne(); } catch ( PsgException e ) { System.err.println( e ); System.exit( -1 ); } } private static double inch( double a ) { return a * 72; } private void showright( String str ) throws PsgException { psg.rmoveto( -psg.stringwidth_x( str ), 0 ); psg.show( str ); } private void ellipser( double x, double y, double rot, double xrad, double yrad, double startangle, double endangle ) throws PsgException { psg.gsave(); psg.translate( x, y ); psg.rotate( rot ); psg.scale( xrad, yrad ); psg.arc( 0, 0, 1, startangle, endangle ); psg.grestore(); } private static final double r3 = Math.sqrt( 3 ); private static final double r3d2 = r3 / 2; private static final float black = 0.0F; private static final float white = 1.0F; private static final float gray = .5F; private double pagewidth, pageheight, logoheight; private double h, s, so2, h1, h2, h3, r1, r1m, h4, h5, r2, step; private double rocketrot, wakewidth, wakexsize; private double wakeysize, wake1ysize, wake3ysize; private void initialize() { logoheight = pageheight * 0.9; h = logoheight; s = h / r3d2; so2 = s / 2; h1 = .07 * h; h2 = .15 * h; h3 = .3 * h; r1 = .12 * s; r1m = .95 * r1; h4 = .55 * h; h5 = h4 + r1 * .7; r2 = .06 * s; step = .03 * s; rocketrot = -13; wakewidth = .01 * s; wakexsize = .30 * s; wakeysize = .4 * r1; wake1ysize = 1.30 * wakeysize; wake3ysize = .70 * wakeysize; } // Rocket wake part 2. private void rocketwake2() throws PsgException { psg.setlinewidth( wakewidth ); psg.newpath(); ellipser( so2, h5, rocketrot, wakexsize, wakeysize, 0, 180 ); psg.stroke(); } // Dark triangle. private void darktriangle() throws PsgException { psg.moveto( 0, 0 ); psg.lineto( so2, h ); psg.lineto( s, 0 ); psg.lineto( 0, 0 ); psg.fill(); } // White hollow. private void whitehollow() throws PsgException { psg.setgray( white ); psg.moveto( s, h1 ); psg.lineto( so2, h1 ); psg.lineto( so2, h2 ); psg.rlineto( -.145 * s, 0 ); psg.rlineto( 0, 1.5 * h1 - h2 ); psg.lineto( .21 * s, 1.5 * h1 ); psg.lineto( .21 * s, h3 ); psg.lineto( so2 - r1 - step, h4 ); psg.lineto( so2 + r1 + step, h4 ); psg.lineto( s - .21 * s, h3 ); psg.lineto( s, h3 ); psg.lineto( s, h1 ); psg.fill(); } // Weird-shaped dark area. private void darkarea() throws PsgException { psg.moveto( so2, h3 ); psg.rlineto( -r1m - step, 0 ); psg.rlineto( 0, step ); psg.rlineto( step, 0 ); psg.rlineto( 0, h4 - h3 - step ); psg.rlineto( 2 * r1m, 0 ); psg.rlineto( 0, - ( h4 - h3 - step ) ); psg.rlineto( step, 0 ); psg.rlineto( 0, -step ); psg.fill(); } // White circle. private void whitecircle() throws PsgException { psg.setgray( white ); psg.arc( so2, h4, r1, 0, 360 ); psg.fill(); } // White circular bite. private void whitebite() throws PsgException { psg.setgray( white ); psg.arc( s - .13 * s, h1 / 2 + r2, r2, 0, 360 ); psg.fill(); } // Rocket. private void rocket() throws PsgException { psg.gsave(); psg.translate( so2, h5 ); psg.rotate( rocketrot ); psg.translate( 0, -wake3ysize ); psg.newpath(); ellipser( .05 * h, -.034 * h, 0, .17 * h, .05 * h, 90, 135 ); ellipser( .05 * h, .034 * h, 0, .17 * h, .05 * h, 225, 270 ); psg.closepath(); psg.setgray( black ); psg.fill(); ellipser( .06 * h, 0, 0, .06 * h, .035 * h, 0, 360 ); psg.setgray( black ); psg.fill(); ellipser( .06 * h, 0, 0, .035 * h, .040 * h, 0, 360 ); psg.setgray( white ); psg.fill(); ellipser( .07 * h, 0, 0, .035 * h, .040 * h, 0, 360 ); psg.setgray( white ); psg.fill(); ellipser( .08 * h, 0, 0, .045 * h, .045 * h, 0, 360 ); psg.setgray( white ); psg.fill(); ellipser( .030 * h, 0, 0, .010 * h, .010 * h, 0, 360 ); psg.setgray( white ); psg.fill(); psg.grestore(); } // Rocket wake part 3. public void rocketwake3() throws PsgException { psg.setlinewidth( wakewidth ); psg.newpath(); ellipser( so2, h5, rocketrot, wakexsize, wake3ysize, 277, 360 ); psg.stroke(); } // Rocket wake part 1. private void rocketwake1() throws PsgException { psg.newpath(); psg.setlinewidth( .9 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 180, 190 ); psg.stroke(); psg.newpath(); psg.setlinewidth( .8 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 190, 200 ); psg.stroke(); psg.newpath(); psg.setlinewidth( .7 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 200, 210 ); psg.stroke(); psg.newpath(); psg.setlinewidth( .6 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 210, 220 ); psg.stroke(); psg.newpath(); psg.setlinewidth( .5 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 220, 230 ); psg.stroke(); psg.newpath(); psg.setlinewidth( .4 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 230, 240 ); psg.stroke(); psg.newpath(); psg.setlinewidth( .3 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 240, 250 ); psg.stroke(); psg.newpath(); psg.setlinewidth( .2 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 250, 260 ); psg.stroke(); psg.newpath(); psg.setlinewidth( .1 * wakewidth ); ellipser( so2, h5, rocketrot, wakexsize, wake1ysize, 260, 270 ); psg.stroke(); } // Logo text. private void yoyotext() throws PsgException { psg.setgray( black ); double off1 = ( h2 - h1 ) * .2; psg.setfont( "Helvetica", Font.ITALIC, h3 - h2 ); psg.moveto( so2 + off1, h2 + off1 ); psg.show( "YOYODYNE" ); psg.setfontSize( h2 - h1 ); psg.moveto( so2 + off1, h1 + off1 ); psg.show( "PROPULSION SYSTEMS" ); } // Non-logo text. private void showtext() throws PsgException { double s = 15; psg.setgray( black ); psg.setfont( "TimesRoman", Font.ITALIC, s ); psg.moveto( pagewidth - inch( 0.20 ), pageheight - ( pageheight - logoheight ) / 2 - s ); showright( "The Future Begins Tomorrow" ); } // Finally, actually draw something. private void yoyodyne() throws PsgException { psg.clippath(); double bb[] = psg.pathbbox(); pagewidth = bb[2] - bb[0]; pageheight = bb[3] - bb[1]; initialize(); psg.gsave(); psg.translate( inch( .20 ), ( pageheight - logoheight ) / 2 ); psg.setgray( black ); rocketwake2(); psg.setrgbcolor( 0.0F, .7F, 0.0F ); darktriangle(); whitehollow(); psg.setrgbcolor( 0.0F, .7F, 0.0F ); darkarea(); whitecircle(); whitebite(); rocket(); psg.setgray( black ); rocketwake3(); psg.setgray( black ); rocketwake1(); yoyotext(); psg.grestore(); showtext(); } // Main program, so we can run as an application too. public static void main( String[] args ) { new Acme.MainFrame( new Yoyo(), args, 600, 400 ); } }