This is PlanetView.m in view mode; [Download] [Up]
/* Standard Includes */ #import "Thinker.h" #import <appkit/NXImage.h> #import <appkit/Panel.h> /* for NXRunAlertPanel() */ #import <appkit/appkit.h> #import <dpsclient/wraps.h> #import <libc.h> #import <math.h> #import <appkit/NXColorWell.h> #import <appkit/Form.h> #import <appkit/Slider.h> /* For those of you who want to know what version you are using. */ /* Includes for this project. */ #import "PlanetView.h" @implementation PlanetView - initFrame:(NXRect *)frameRect { int i; printf("SD %d\n", SPACEDIST); [super initFrame:frameRect]; srandom(getpid()); if (!myPrefWindow) { myPrefWindow = [NXApp loadNibSection:"PlanetPrefs.nib" owner:self]; } numplanets = 1; if (!myplanets) { myplanets = (aplanet *) malloc(numplanets * sizeof(aplanet)); } for (i = 0; i < numplanets; i++) { [self newPlanet:&myplanets[i] :bounds.size.width:bounds.size.height]; } winNum = [[self window] windowNum]; return self; } /* Animate() */ /* Move the planets around. */ - oneStep { register int i, j; /* planet index */ register double xfactor, yfactor; /* These variables are related to mouse control of the wasp. */ PScurrentmouse(winNum, &curX, &curY); /* Test the cursor */ if (bounds.size.width - curX + bounds.size.height - curY <= 10.0) [self showPanel]; /* Erase previous, draw current, sync for smoothness. */ PSsetlinecap(1); PSsetinstance(1); PSnewinstance(); /* Do physics... */ if (numplanets < (j = [numplanetForm intValueAt:0])) { myplanets = (aplanet *) realloc(myplanets, (j + 1) * sizeof(aplanet)); for (i = numplanets; i < j; i++) [self newPlanet:&myplanets[i] :bounds.size.width:bounds.size.height]; numplanets = j; } i = -1; while (++i < numplanets) { myplanets[i].x += myplanets[i].xv; myplanets[i].y += myplanets[i].yv; if (abs(myplanets[i].x) > bounds.size.width || abs(myplanets[i].y) > bounds.size.height) myplanets[i] = myplanets[--numplanets]; NXSetColor(myplanets[i].planetcolor); PSmoveto(myplanets[i].x + bounds.size.width / 2, myplanets[i].y + bounds.size.height / 2); if (myplanets[i].gravity <= 0) { myplanets[i].gravity += 1.0; PSsetlinewidth(SPACEDIST * sqrt(abs(myplanets[i].gravity))); } else PSsetlinewidth(SPACEDIST * sqrt(myplanets[i].gravity)); PSrlineto(1, 0); PSstroke(); for (j = i + 1; j < numplanets; j++) { float dist = sqrt(SQR(deltaX(i, j)) + SQR(deltaY(i, j))) / SPACEDIST; /* printf("j %d %f\n", j, dist); */ if (dist * 2 < sqrt(myplanets[i].gravity) + sqrt(myplanets[j].gravity)) { [self merge:i :j]; continue; } myplanets[i].xv += (xfactor = deltaX(i, j) / (SQR(dist) * dist)) * myplanets[j].gravity; myplanets[i].yv += (yfactor = deltaY(i, j) / (SQR(dist) * dist)) * myplanets[j].gravity; myplanets[j].xv -= xfactor * myplanets[i].gravity; myplanets[j].yv -= yfactor * myplanets[i].gravity; } if (cursortime) { float grav = [cursorGravity floatValue]; float dist = sqrt(SQR(((curX - bounds.size.width / 2) - myplanets[i].x)) + SQR(((curY - bounds.size.height / 2) - myplanets[i].y))) / SPACEDIST; if (dist < sqrt(grav)) continue; ; /* * printf("%d x %f y %f cx %f cy %f grav %f dist %f xpull %f\n", i, * myplanets[i].x, myplanets[i].y, (curX - bounds.size.width / 2), * (curY - bounds.size.height / 2), grav, dist, ((curX - * bounds.size.width / 2) - myplanets[i].x) * grav / (SQR(dist) * * dist)); */ myplanets[i].xv += ((curX - bounds.size.width / 2) - myplanets[i].x) * grav / (SQR(dist) * dist); myplanets[i].yv += ((curY - bounds.size.height / 2) - myplanets[i].y) * grav / (SQR(dist) * dist); } } PSstroke(); return self; } - setCursorhasGravity:sender { cursortime = !cursortime; return self; } - (BOOL)useBufferedWindow { return NO; } - showPanel { int inspectedPlanet; [myPrefWindow orderFront:nil]; inspectedPlanet = MIN(numplanets - 1,[planetnumForm intValueAt:0]); [numplanetForm setIntValue:[numplanetSlider intValue] at:0]; [numplanetSlider setIntValue:MIN(numplanets,[numplanetSlider intValue])]; [planetnumForm setIntValue:inspectedPlanet at:0]; [planetnumSlider setIntValue:inspectedPlanet]; [planetnumSlider setMaxValue:numplanets - 1]; [planetSpecs setFloatValue:myplanets[inspectedPlanet].gravity at:0]; [planetgravitySlider setFloatValue:myplanets[inspectedPlanet].gravity]; [planetSpecs setFloatValue:myplanets[inspectedPlanet].x at:1]; [planetSpecs setFloatValue:myplanets[inspectedPlanet].y at:2]; [planetSpecs setFloatValue:myplanets[inspectedPlanet].xv at:3]; [planetSpecs setFloatValue:myplanets[inspectedPlanet].yv at:4]; [planetColor setColor:myplanets[inspectedPlanet].planetcolor]; return self; } - setPlanetNumber:sender { int inspectedPlanet = MIN(numplanets - 1,[sender intValue]); [planetnumForm setIntValue:inspectedPlanet at:0]; [planetnumSlider setIntValue:inspectedPlanet]; [self showPanel]; return self; } - setNumberPlanets:sender { int numberPlanets = [sender intValue]; [numplanetForm setIntValue:numberPlanets at:0]; [numplanetSlider setIntValue:numberPlanets]; return self; } - setPlanetSpex:sender { int inspectedPlanet; inspectedPlanet = MIN(numplanets - 1,[planetnumSlider intValue]); myplanets[inspectedPlanet].gravity = [planetSpecs floatValueAt:0]; myplanets[inspectedPlanet].x = [planetSpecs floatValueAt:1]; myplanets[inspectedPlanet].y = [planetSpecs floatValueAt:2]; myplanets[inspectedPlanet].xv = [planetSpecs floatValueAt:3]; myplanets[inspectedPlanet].yv = [planetSpecs floatValueAt:4]; myplanets[inspectedPlanet].planetcolor = [planetColor color]; [self showPanel]; return self; } - setPlanetGravity:sender { int inspectedPlanet; inspectedPlanet = MIN(numplanets - 1,[planetnumSlider intValue]); myplanets[inspectedPlanet].gravity = [sender floatValue]; [self showPanel]; return self; } - setFollow:sender { cursortime = [sender intValue]; return self; } - merge:(int)planetA :(int)planetB { myplanets[planetA].gravity = myplanets[planetA].gravity + myplanets[planetB].gravity; myplanets[planetA].xv = (myplanets[planetA].xv * myplanets[planetA].gravity + MIN(100,myplanets[planetB].xv) * myplanets[planetB].gravity) / (myplanets[planetA].gravity + myplanets[planetB].gravity); myplanets[planetA].yv = (myplanets[planetA].yv * myplanets[planetA].gravity + MIN(100,myplanets[planetB].yv) * myplanets[planetB].gravity) / (myplanets[planetA].gravity + myplanets[planetB].gravity); myplanets[planetB] = myplanets[--numplanets]; if ((int)myplanets[planetA].gravity > 100) [self blowPlanet:planetA]; return self; } - newPlanet:(aplanet *) newplanet :(float)width :(float)height { newplanet->x = 1.0 * RAND(1100); newplanet->y = 1.0 * RAND(1100); newplanet->gravity = DEFAULTGRAV; newplanet->planetcolor = NXConvertGrayToColor(NX_WHITE); newplanet->xv = SPACEDIST * RAND(300) / 200.0; newplanet->yv = SPACEDIST * RAND(300) / 200.0; return self; } - doBOOM:sender { [self blowPlanet:MIN(numplanets - 1,[planetnumSlider intValue])]; [self showPanel]; return self; } - blowPlanet:(int)planetNum { int i, newplanets = abs(myplanets[planetNum].gravity), newplanetnum; double newxd, newyd, newradius; newradius = newplanets / PI; newplanetnum = numplanets + newplanets; myplanets = (aplanet *) realloc(myplanets, (newplanetnum + 5) * sizeof(aplanet)); for (i = numplanets; i < newplanetnum; i++) { myplanets[i] = myplanets[planetNum]; newxd = sin(PI * 2 * (i - numplanets) / (newplanets)) * newradius; newyd = cos(PI * 2 * (i - numplanets) / (newplanets)) * newradius; /* myplanets[i].xv = newxv / 2 * sqrt(myplanets[planetNum].gravity); */ /* myplanets[i].yv = newyv / 2 * sqrt(myplanets[planetNum].gravity); */ myplanets[i].x += newxd / 0.5; myplanets[i].y += newyd / 0.5; myplanets[i].gravity = DEFAULTGRAV; /* myplanets[i].planetcolor = myplanets[planetNum].planetcolor; */ } myplanets[planetNum].gravity *= -1.0 / 2; numplanets = newplanetnum; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.