This is RandomGenerator.m in view mode; [Download] [Up]
/*
* A random distribution generator tool. knows how to get different views
* from a holding place and display them in another view. There is a
* pop-down menu in the nib file (Random.nib), that chooses which one.
*
* Copyright (c) 1993 Gil Rivlis
*/
#import "RandomGenerator.h"
/* just a short cut */
double distance(double x, double y, double centerX, double centerY)
{
return (x-centerX)*(x-centerX)+ (y-centerY)*(y-centerY);
}
@implementation RandomGenerator
/* When we awakeFromNib we set the initial choice for a view. */
- awakeFromNib
{
whichApply = ISOTROPIC;
[self setDistToView:[isotropicView contentView] ];
return self;
}
/* Returns the window, so we can orderFront when initializing */
- window
{
return window;
}
/* Gets called by the pop-up menu and sets the distribution view we want */
- setDistribution:sender
{
id newView = nil;
whichApply = [[sender selectedCell] tag]; //tagged as in the header file
switch (whichApply) {
case ISOTROPIC:
newView = [isotropicView contentView];
break;
case GAUSSIAN:
newView = [gaussianView contentView];
break;
case STEP:
newView = [stepView contentView];
break;
}
[self setDistToView:newView];
return self;
}
/* Sets the wanted view in multiView (which is the only view we actually see */
- setDistToView:theView
{
NXRect boxRect, viewRect;
[multiView getFrame:&boxRect];
[theView getFrame:&viewRect];
[multiView setContentView:theView];
NX_X(&viewRect) = (NX_WIDTH(&boxRect)-NX_WIDTH(&viewRect)) / 2.0;
NX_Y(&viewRect) = (NX_HEIGHT(&boxRect)-NX_HEIGHT(&viewRect)) / 2.0;
[theView setFrame:&viewRect];
[multiView display];
return self;
}
/* obvious */
- apply:sender
{
switch (whichApply) {
case ISOTROPIC: [self isotropicDraw];
break;
case GAUSSIAN: [self gaussianDraw];
break;
case STEP: [self stepDraw];
break;
}
return self;
}
/* constant distribution draw */
- isotropicDraw
{
int i;
float density = [isoPercentField floatValue]; // How dense ?
lifeView = [theGenerator lifeView];
theUniverse = [lifeView universe];
popSize = 0; // reset popSize locally
// Allocate enough memory
population = malloc(sizeof(char)*theUniverse.width*theUniverse.height);
srand( (unsigned) time(NULL) % UINT_MAX );
for (i=0; i<theUniverse.width*theUniverse.height; i++) {
if ( (rand() % 100) < density ) { //rand modulo 100...
population[i] = 10;
popSize++;
}
else {
population[i] = 0;
}
}
[theGenerator clear:nil];
[lifeView showPopulation:population ofSize:popSize]; // display
free(population);
return self;
}
- gaussianDraw
{
int x,y;
float density = [gaussPercentField floatValue]; // the density
float width = [gaussWidthField floatValue]/2.0; // make it radius
double centerX,centerY,radsq;
lifeView = [theGenerator lifeView];
theUniverse = [lifeView universe];
/* don't compute too much... */
radsq =(width*(double)(theUniverse.width)/100.0)*
(width*(double)(theUniverse.width)/100.0);
centerX = theUniverse.width/2;
centerY = theUniverse.height/2;
popSize = 0;
population = malloc(sizeof(char)*theUniverse.width*theUniverse.height);
srand( (unsigned) time(NULL) % UINT_MAX );
for (y=0; y<theUniverse.height;y++) {
for(x=0; x<theUniverse.width;x++) {
if ( ((int)density % 100)*exp(((-1)*distance((double)x, (double)y, centerX, centerY) )/radsq ) > (rand() % 100)) {
population[y*theUniverse.width + x] = 10;
popSize++;
}
else {
population[y*theUniverse.width + x] = 0;
}
}
}
[theGenerator clear:nil];
[lifeView showPopulation:population ofSize:popSize];
free(population);
return self;
}
/* fixed density at the center with some width */
- stepDraw
{
int x,y;
float density = [stepDensityField floatValue]; // the density
float width = [stepWidthField floatValue]/2.0; // make it radius
double centerX,centerY,radsq;
lifeView = [theGenerator lifeView];
theUniverse = [lifeView universe];
/* don't compute too much... */
radsq =(width*(double)(theUniverse.width)/100.0)*
(width*(double)(theUniverse.width)/100.0);
centerX = theUniverse.width/2;
centerY = theUniverse.height/2;
popSize = 0;
population = malloc(sizeof(char)*theUniverse.width*theUniverse.height);
srand( (unsigned) time(NULL) % UINT_MAX );
for (y=0; y<theUniverse.height;y++) {
for(x=0; x<theUniverse.width;x++) {
if ( ((rand() % 100) < density) &&
( distance((double)x, (double)y, centerX, centerY) < radsq) ) {
population[y*theUniverse.width + x] = 10;
popSize++;
}
else {
population[y*theUniverse.width + x] = 0;
}
}
}
[theGenerator clear:nil];
[lifeView showPopulation:population ofSize:popSize];
free(population);
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.