This is chaosView.m in view mode; [Download] [Up]
/* Generated by Interface Builder */ #import "chaosView.h" #import <dpsclient/wraps.h> #import <stdlib.h> #import <stdio.h> #import <appkit/nextstd.h> // For MIN MAX #import <appkit/Application.h> #import <appkit/color.h> @implementation chaosView - gohome: (float *)newX: (float *)newY: (float *)newDX: (float *)newDY:(int *)newDepth { *newX = 0.0; *newY = 0.0; *newDX = 4; *newDY = 4; *newDepth = 150; return self; } - (int)colorindex:(double)Real :(double)Imaginary { register double realCoord = Real, imaginaryCoord = Imaginary, tempdouble; register int i; //printf("\nReal %lf Imaginary %lf depth %d\n", Real, Imaginary, *Depth); for (i = 0; i < Depth; i++) { if ((Real >= 2) || (Imaginary >= 2) || (Real <= -2) || (Imaginary <= -2)) { return ((int)(chaosColors) * i / Depth); } tempdouble = Real * Real - Imaginary * Imaginary + realCoord; Imaginary = 2 * Real * Imaginary + imaginaryCoord; Real = tempdouble; } return (chaosColors); } - initView:(double) maxsize { NXRect myRect; [self lockFocus]; NXSetRect(&myRect, 0, 0, maxsize, maxsize); printf("ms %f", maxsize); NXSetColor(mycolorMap[[self colorindex:(myRect.origin.x - bounds.size.width / 2) * xFactor + myCenterX:(myRect.origin.y - bounds.size.height / 2) * yFactor + myCenterY]]); NXRectFill(&myRect); [self display]; [self unlockFocus]; return self; } - startM:(float)XCenter :(float)YCenter :(float)XScale :(float)YScale :(int)ThisDepth; { double bigsize = MAX(bounds.size.width, bounds.size.height); myCenterX = XCenter; myCenterY = YCenter; myWidth = XScale; myHeight = XScale * bounds.size.height / bounds.size.width; Depth = MAX(ThisDepth, 1); twofactor = 1.0; while (twofactor < bigsize) twofactor *= 2.0; currentRow = 0.0; currentCol = 0.0; xsize = twofactor / 2.0; xstep = twofactor; ysize = twofactor / 2.0; ystep = twofactor; xFactor = myWidth / bounds.size.width; yFactor = xFactor; [self initView:bigsize]; return self; } - initFrame:(const NXRect *)frameRect { [super initFrame:frameRect]; return self; } - fillbox:(NXRect)myRect { float boxsize, *thisptr, endpt; if (myRect.size.width < myRect.size.height) { boxsize = myRect.size.width; thisptr = &myRect.origin.y; endpt = *thisptr + myRect.size.height; } else { boxsize = myRect.size.height; thisptr = &myRect.origin.x; endpt = *thisptr + myRect.size.width; } [self lockFocus]; for (*thisptr = *thisptr; *thisptr <= endpt; *thisptr += boxsize) { NXSetColor(mycolorMap[[self colorindex:(myRect.origin.x - bounds.size.width / 2) * xFactor + myCenterX:(myRect.origin.y - bounds.size.height / 2) * yFactor + myCenterY]]); NXRectFill(&myRect); } [self display]; [self unlockFocus]; return self; } - drawline { NXRect myRect; #ifdef DEBUG printf("drawlines1\n"); #endif [self lockFocus]; #ifdef DEBUG printf("drawlines2\n"); #endif for (currentCol = 0; currentCol < bounds.size.width; currentCol += xstep) { #ifdef DEBUG printf("drawlines3"); #endif //printf("%lf %lf %lf\n", x->coord, y->coord, y->size); NXSetRect(&myRect, currentCol + xsize, currentRow, xsize, ysize); #ifdef DEBUG printf(".1"); #endif NXSetColor(mycolorMap[[self colorindex:(currentCol + xsize - bounds.size.width / 2) * xFactor + myCenterX:(currentRow - bounds.size.height / 2) * yFactor + myCenterY]]); #ifdef DEBUG printf(".2"); #endif NXRectFill(&myRect); #ifdef DEBUG printf(".3\n"); #endif NXSetRect(&myRect, currentCol + xsize, currentRow + ysize, xsize, ysize); NXSetColor(mycolorMap[[self colorindex:(currentCol + xsize - bounds.size.width / 2) * xFactor + myCenterX:(currentRow + ysize - bounds.size.height / 2) * yFactor + myCenterY]]); NXRectFill(&myRect); NXSetRect(&myRect, currentCol, currentRow + ysize, xsize, ysize); NXSetColor(mycolorMap[[self colorindex:(currentCol - bounds.size.width / 2) * xFactor + myCenterX:(currentRow + ysize - bounds.size.height / 2) * yFactor + myCenterY]]); NXRectFill(&myRect); [self display]; } if (currentRow + ystep >= bounds.size.height) { currentRow = 0.0; twofactor /= 2.0; if (xsize <= 1.0) { [CVchaosControl runstop:self]; //DPSRemoveTimedEntry(windowEvent); //windowEvent = 0; } xsize = twofactor / 2.0; xstep = twofactor; ysize = twofactor / 2.0; ystep = twofactor; } else currentRow += ystep; [self unlockFocus]; return self; } - examinSelected:(float)realCenter : (float)imagineCenter : (float)realScale : (float)imagineScale : (int)newDepth { NXRect myRect; float RealCenter = (realCenter - myCenterX) / xFactor + bounds.size.width / 2; float ImagineCenter = (imagineCenter - myCenterY) / yFactor + bounds.size.height / 2; float RealScale = realScale / xFactor; float ImagineScale = imagineScale / yFactor; NXCoord bottomrow = ImagineCenter - ImagineScale / 2.0, leftcol = RealCenter - RealScale / 2.0, toprow = bottomrow + ImagineScale, rightcol = leftcol + RealScale; NXCoord *x, *y; printf("RC %f IC %f RS %f IS %f\n", RealCenter, ImagineCenter, RealScale, ImagineScale); printf("br %f lc %f\n", bottomrow, leftcol); //scanf("%*s"); NXSetRect(&myRect, leftcol, bottomrow, (NXCoord)1.0, (NXCoord)1.0); x = &myRect.origin.x; y = &myRect.origin.y; [self lockFocus]; for (*y = *y; *y <= toprow; *y += 1.0) { *x = leftcol; for (*x = *x; *x <= rightcol; *x += 1.0) { #ifdef DEBUG printf("x %f y %f\n", *x, *y); #endif NXSetColor(mycolorMap[[self colorindex:(myRect.origin.x - bounds.size.width / 2) * xFactor + myCenterX:(myRect.origin.y - bounds.size.height / 2) * yFactor + myCenterY]]); NXRectFill(&myRect); } } [self display]; [self unlockFocus]; return self; } - scrollup { const NXRect *thisRect = &bounds; NXRect fillRect; const NXPoint thisPoint = {0, -ysize}; [self lockFocus]; [self scrollRect:thisRect by:&thisPoint]; currentRow -= ysize; myCenterY += ysize * yFactor; NXSetRect(&fillRect, thisRect->origin.x, thisRect->size.height - ysize, thisRect->size.width, ysize); [self fillbox:fillRect]; [self unlockFocus]; return self; } - scrollright { const NXRect *thisRect = &bounds; NXRect fillRect; const NXPoint thisPoint = {-xsize, -0}; [self lockFocus]; [self scrollRect:thisRect by:&thisPoint]; currentCol -= xsize; myCenterX += xsize * xFactor; NXSetRect(&fillRect, thisRect->size.width - xsize, thisRect->origin.y, xsize, thisRect->size.height); [self fillbox:fillRect]; [self unlockFocus]; return self; } - scrolldown { const NXRect *thisRect = &bounds; NXRect fillRect; const NXPoint thisPoint = {0, ysize}; [self lockFocus]; [self scrollRect:thisRect by:&thisPoint]; currentRow += ysize; myCenterY -= ysize * yFactor; NXSetRect(&fillRect, thisRect->origin.x, thisRect->origin.y, thisRect->size.width, ysize); [self fillbox:fillRect]; [self unlockFocus]; return self; } - scrollleft { const NXRect *thisRect = &bounds; NXRect fillRect; const NXPoint thisPoint = {xsize, 0}; [self lockFocus]; [self scrollRect:thisRect by:&thisPoint]; currentCol += xsize; myCenterX -= xsize * xFactor; NXSetRect(&fillRect, thisRect->origin.x, thisRect->size.height - ysize, thisRect->size.width, ysize); [self fillbox:fillRect]; NXSetRect(&fillRect, thisRect->origin.x, thisRect->origin.y, xsize, thisRect->size.height); [self fillbox:fillRect]; [self unlockFocus]; return self; } - mouseDown:(NXEvent *)e /* * We implement the mouseDown method so the user can sweep out a section of * the view and select that as the current x,y,scale coordinates. */ { int looping = YES; int oldMask; NXRect bbox; NXPoint startPoint, currPoint; float newX, newY, newDX, newDY; NXCoord aspectRatio; aspectRatio = bounds.size.height / bounds.size.width; //chaosWidth = bounds.size.width; //chaosHeight = bounds.size.height; oldMask = [window addToEventMask:NX_MOUSEDRAGGEDMASK]; startPoint = e->location; [self convertPoint:&startPoint fromView:nil]; NXSetRect(&bbox, startPoint.x, startPoint.y, 0.0, 0.0); [self lockFocus]; while (looping) { e = [NXApp getNextEvent:NX_MOUSEUPMASK | NX_MOUSEDRAGGEDMASK]; currPoint = e->location; [self convertPoint:&currPoint fromView:nil]; bbox.size.width = 2 * (currPoint.x - startPoint.x); bbox.size.height = 2 * (currPoint.y - startPoint.y); /* Normalize bbox to always have positive width and height */ if (bbox.size.width < 0) bbox.size.width = -bbox.size.width; if (bbox.size.height < 0) bbox.size.height = -bbox.size.height; /* * constrain the box to have the aspect ratio of the view. Choose * whichever dimension is closer to the desired result. */ if ((bbox.size.height / bbox.size.width) > aspectRatio) { bbox.size.height = bbox.size.width * aspectRatio; } else { bbox.size.width = bbox.size.height / aspectRatio; } /* The startPoint is always at the center of the bbox */ bbox.origin.x = startPoint.x -.5 * bbox.size.width; bbox.origin.y = startPoint.y -.5 * bbox.size.height; PSnewinstance(); if (looping = (e->type == NX_MOUSEDRAGGED)) { PSsetinstance(YES); PSsetgray(NX_WHITE); NXFrameRect(&bbox); PSsetinstance(NO); } } [self unlockFocus]; [window setEventMask:oldMask]; if ((bbox.size.width > 0) && (bbox.size.height > 0)) { /* * At this point, bbox is in window coordinates. Set new controller * parameters based on this view's coordinates and the bounding box. */ newX = (startPoint.x - bounds.size.width / 2) * xFactor + myCenterX; newY = (startPoint.y - bounds.size.height / 2) * yFactor + myCenterY; newDX = bbox.size.width * xFactor; newDY = bbox.size.height * yFactor; //using myWidth / bounds.size.width was more accurate(too accurate at small widths ?) /* * Note that we only update the text fields in the mandelControl -- we * don't update the internal instance variables. If we were to update * the internal ivs, then the user would only get one chance with the * mouse down method because subsequent mouse-downs would work in terms * of the new coordinate system. */ [CVchaosControl setParameters : newX :newY :newDX :newDY]; } return self; } - sizeTo:(NXCoord)width :(NXCoord)height // boy, this looks obsolete ! { [super sizeTo:width :height]; return self; } - setColors:(NXColor *) colorMap :(int)colors :(NXColor) setColor; { int i; printf("%d colors\n", colors); if (mycolorMap) free(mycolorMap); mycolorMap = (NXColor *) malloc(sizeof(NXColor) * (colors + 1)); chaosColors = colors; for (i = 0; i < colors; i++) mycolorMap[i] = colorMap[i]; mycolorMap[colors] = setColor; return self; } - getController:sender :map { CVchaosControl = sender; CVcolorMap = map; //[self startM:0.0:0.0:4 :4 :100]; [CVcolorMap updateChaosView:self]; return self; } @end // ------------------------------------------------------------------- void mulCoords(double *Real1, double *Imagine1, double *Real2, double *Imagine2) { //Returns coord1 * coord2 in coord1(for imaginary coords) //Aux function proves useful ! ! double returnReal, returnImagine; returnReal = ((*Real1) * (*Real2)) - ((*Imagine1) * (*Imagine2)); returnImagine = ((*Real1) * (*Imagine2)) + ((*Real2) * (*Imagine1)); *Real1 = returnReal; *Imagine1 = returnImagine; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.