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.