ftp.nice.ch/pub/next/tools/screen/backspace/old/PlanetView.N.bs.tar.gz#/PlanetView/PlanetView.m

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.