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.