This is LorenzRotateViewPart.m in view mode; [Download] [Up]
//This code is the work of Booker C. Bense (benseb@next.sdsc.edu)
// You are free to change/distribute this code provided this notice
// remains intact in all versions.
#import "LorenzRotateViewPart.h"
#import "Thinker.h"
#import <appkit/NXImage.h>
#import <appkit/Panel.h> // for NXRunAlertPanel()
#import <dpsclient/wraps.h>
#import <libc.h>
#import <math.h>
@implementation LorenzRotateView
- oneStep
{
register int i;
int rect_count;
float xx,yy,zz,ctheta,stheta;
// Cycle indices
p=n;
points[0] = n;
theta += TWO_PI / NTHETA ;
if ( theta > TWO_PI ) theta -= TWO_PI;
ctheta = cos(theta);
stheta = sin(theta);
for( i = 1 ; i < CHASERS ; i++ )
{
points[i] = (CHASELEN +points[i-1])%(NUMPOINTS);
}
n=(n+1)%(NUMPOINTS);
// take an euler step
xdot = S * (Y[p] - X[p]);
ydot = (R * X[p]) - Y[p] - (X[p] * Z[p]);
zdot = (X[p] * Y[p]) - (B * Z[p]);
X[n] = X[p] + xdot * delta_T;
Y[n] = Y[p] + ydot * delta_T;
Z[n] = Z[p] + zdot * delta_T;
// Draw the black stuff
PSsetrgbcolor(0.0,0.0,0.0);
// This one's faster
NXRectFill(&curBounds);
// NXRectFillList( pixels,NUMPOINTS );
//Convert to screen coordinates Update
for ( i = 0 ; i < NUMPOINTS ; i++)
{
xx = (( X[i] - Xmin)/ Xrange) - 0.5;
yy = (( Y[i] - Ymin )/ Yrange) -0.5;
zz = (( Z[i] - Zmin )/ Zrange) -0.5;
pixels[i].origin.x = (xx)* urx + midx;
pixels[i].origin.y = (ctheta*yy+stheta*zz )*ury + midy ;
pixels[i].size.width =
pixels[i].size.height = ceil(3*(-stheta*yy+ctheta*zz) + 1.5) ;
}
if ( [self shouldDrawColor ] )
{
red_shift = (CHASERS*4)/3;
blue_shift = (CHASERS*2)/3;
clut = cl_clut;
}
else
{
red_shift = 0;
blue_shift = 0;
clut = twobit_clut;
}
for ( i = 0; i < CHASERS ; i++)
{
pixelpoint = &pixels[points[i]];
// worry about cycling indices
if( ( NUMPOINTS - points[i] ) < CHASELEN )
rect_count = (NUMPOINTS -points[i]);
else
rect_count = CHASELEN;
PSsetrgbcolor(
clut[(i+red_shift)%CHASERS],clut[i],
clut[(i+blue_shift)%CHASERS]);
NXRectFillList(pixelpoint,rect_count);
if ( rect_count < CHASELEN )
NXRectFillList(pixels,(CHASELEN-rect_count));
}
// Draw the White stuff
// worry about cycling indices
if( ( n - CHASELEN) < 0)
{
rect_count = -(n-CHASELEN);
pixelpoint = &pixels[NUMPOINTS-rect_count];
}
else
{
rect_count = CHASELEN;
pixelpoint = &pixels[n-CHASELEN+1];
}
PSsetrgbcolor(1.0, 1.0, 1.0);
NXRectFillList(pixelpoint,rect_count);
if ( rect_count < CHASELEN )
NXRectFillList(pixels,n+1);
return self;
}
- initFrame:(NXRect *)frameRect
{
[super initFrame:frameRect];
[self newSize];
return self;
}
- sizeTo:(NXCoord)width :(NXCoord)height
{
[super sizeTo:width :height];
[self newSize];
return self;
}
- newSize
{
register int j,i;
curBounds = bounds;
urx=bounds.size.width;
ury=bounds.size.height;
midx=urx/2;
midy=ury/2;
// play with size clues later
for ( j = 0 ; j < NUMPOINTS; j++)
{
pixels[j].size.width = 1.0;
pixels[j].size.height = 1.0;
}
// angle of rotation
theta = 0.0;
X[0] = 0.1;
Y[0] = 0.1;
Z[0] = 0.1;
xc[0] = midx;
yc[0] = midy;
// Starting points
for(i=1; i< NUMPOINTS; i++)
{
xdot = S * (Y[i-1] - X[i-1]);
ydot = (R * X[i-1]) - Y[i-1] - (X[i-1] * Z[i-1]);
zdot = (X[i-1] * Y[i-1]) - (B * Z[i-1]);
X[i] = X[i-1] + xdot * delta_T;
Y[i] = Y[i-1] + ydot * delta_T;
Z[i] = Z[i-1] + zdot * delta_T;
pixels[i].origin.x = (( X[i] - Xmin)/ Xrange)*urx ;
pixels[i].origin.y = (( Y[i] - Ymin )/ Yrange)*ury ;
}
n = NUMPOINTS - 1;
//this will probably look really ugly in color ????
for(i=0; i < CHASERS ; i++ )
{ cos_arg = ((float)i)/((float)CHASERS)*PI;
cl_clut[i] = (cos(cos_arg)+1.0)/2.0;
twobit_clut[i] = (float)((i%3)+1)/3.0;
}
return self;
}
@end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.