Logo Search packages:      
Sourcecode: adun.app version File versions  Download package

AdunGrid.m

/*
   Project: Adun

   Copyright (C) 2005 Michael Johnston & Jordi Villa-Freixa

   Author: Michael Johnston

   This application is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public
   License as published by the Free Software Foundation; either
   version 2 of the License, or (at your option) any later version.

   This application is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU General Public
   License along with this library; if not, write to the Free
   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#include "AdunKernel/AdunGrid.h"

00024 @implementation AdGrid

- (void) _trimGridToCavity
{
      int i,j, k;
      int cavityPoints;
      int* cavityArray;
      AdMatrix* newGrid;

      cavityArray = (int*)malloc(gridPoints*sizeof(int));
      for(cavityPoints=0, i=0; i<gridPoints; i++)
            if([cavity isPointInCavity: grid->matrix[i]])
            {
                  cavityArray = i;
                  cavityPoints++;
            }

      NSDebugLLog(@"AdGrid", @"There are %d points in the cavity", cavityPoints);

      newGrid = [memoryManager allocateMatrixWithRows: cavityPoints withColumns: 3];
      for(i=0; i<cavityPoints; i++)
            for(j=0; j<3; j++)
                  newGrid->matrix[i][j] = grid->matrix[cavityArray[i]][j];

      free(cavityArray);
      [memoryManager freeMatrix: grid];
      grid = newGrid;
      gridPoints = cavityPoints;
}

- (void)  _createGrid
{
      int i, j, k, count;
      Vector3D originOffset;
      Vector3D* centre;

      for(gridPoints = 1, i=0; i<3; i++)
            gridPoints *= ticksPerAxis[i]; 
      
      NSDebugLLog(@"AdGrid", @"Number of grid points is %d.\n", gridPoints);

      //first we create the grid in the (+,+,+) sector. Then we move it so its
      //centred on the origin
            
      grid = [memoryManager allocateMatrixWithRows: gridPoints
                        withColumns: 3];

      NSDebugLLog(@"AdGrid", @"Allocating grid points");

      count = 0;
      for(i=0; i < ticksPerAxis; i++)
            for(j=0; j< ticksPerAxis; j++)
                  for(k=0; k < ticksPerAxis; k++)
                  {
                        grid->matrix = i*[[gridSpacing objectAtIndex:0] doubleValue];
                        grid->matrix = j*[[gridSpacing objectAtIndex:1] doubleValue];
                        grid->matrix = k*[[gridSpacing objectAtIndex:2] doubleValue];
                        count++;
                  }

      NSDebugLLog(@"AdGrid", @"Moving grid to origin");
      
      //move to origin  

      for(i=0; i< 3; i++)
            originOffset->vector[i] = -1*((ticksPerAxis[i]-1)*[[gridSpacing objectAtIndex:i] doubleValue])/2;

      [self translateBy: originOffset];

      //now translate everything to the cavity center
      
      centre = [cavity cavityCentre];
      cavityCentre.vector = centre->vector;
      cavityCentre.vector = centre->vector;
      cavityCentre.vector = centre->vector;

      NSDebugLLog(@"AdGrid", @"Moving grid to cavity center");
      [self translateBy: &cavityCentre];

      //trim the grid by removing points not in the cavity

      NSDebugLLog(@"AdGrid", @"Trimming grid to cavity");
      [self _trimGridToCavity];
}

/********************

Object Creation

**********************/

- (void) _cavityInitialisation
{
      int axisLength, i;
      NSEnumerator* extremeEnum;
      id extreme;

      cavityExtremes = [cavity cavityExtremes];

      NSDebugLLog(@"AdGrid", @"Cavity Extremes %@", cavityExtremes);

      extremeEnum = [cavityExtremes objectEnumerator];
      i = 0;
      while(extreme = [extremeEnum nextObject])
      {
            axisLength = [[extreme objectAtIndex: 0] intValue] - [[extreme objectAtIndex: 1] intValue];
            ticksPerAxis = ceil(axisLength/[[gridSpacing objectAtIndex: i] doubleValue]);
            NSDebugLLog(@"AdGrid", @"There are %d ticks on axis %d", ticksPerAxis[i], i);
            i++;
      }

      NSDebugLLog(@"AdGrid", @"%@ %@", gridSpacing, cavityExtremes);
}

- (id) init
{
      return [self initWithEnvironment: nil];
}

00143 - (id) initWithEnvironment: (id) object
{
      return [self initWithEnvironment: object observe: YES];
}

00148 - (id) initWithEnvironment: (id) object observe: (BOOL) value
{
      if(self = [super initWithEnvironment: object observe: value])
      {
            isTranslationEnabled = YES;
            memoryManager = [AdMemoryManager appMemoryManager];
            grid = NULL;
            if(environment != nil)
            {
                  [self synchroniseWithEnvironment];
                  [self registerWithEnvironment];
            }
      }

      return self;
}

//Specialised initialisers

+ (id) gridWithDensity: (double) density cavity: (id) aCavity environment: (id) object
{
      id gridObject;

      gridObject = [[AdGrid alloc] initWithDensity: density
                  cavity: aCavity
                  environment: object];

      return [gridObject autorelease];
}

+ (id) gridWithDivisions: (NSArray*) divisions cavity: (id) aCavity environment: (id) object
{
      id gridObject;

      gridObject = [[AdGrid alloc] initWithDivisions: divisions
                  cavity: aCavity
                  environment: object];

      return [gridObject autorelease];
}

+ (id) gridWithSpacing: (NSArray*) spacing cavity: (id) aCavity environment: (id) object
{
      id gridObject;

      gridObject = [[AdGrid alloc] initWithSpacing: spacing
                  cavity: aCavity
                  environment: object];

      return [gridObject autorelease];
}

00200 - (id) initWithDensity: (double) density cavity: (id) cavity environment: (id) object
{
      NSWarnLog(@"Method %@ not implemented", NSStringFromSelector(_cmd));
      return nil;
}

00206 - (id) initWithDivisions: (NSArray*) divisions cavity: (id) cavity environment: (id) object
{
      NSWarnLog(@"Method %@ not implemented", NSStringFromSelector(_cmd));
      return nil;
}

00212 - (id) initWithSpacing: (NSArray*) spacing cavity: aCavity environment: (id) object
{
      [self initWithEnvironment: object];
      gridSpacing = [[spacing copy] retain];
      [self setCavity: aCavity];

      return self;
}

- (void) dealloc
{
      [gridSpacing release];
      [memoryManager freeMatrix: grid];
}

/*
 * Environment observation
 */

00231 - (void) updateForKey: (NSString*) key value: (id) value object: (id) object
{
      //no updates as of yet
}

00236 - (void) registerWithEnvironment
{
      //nothing to register
}

00241 - (void) deregisterWithEnvironment
{
      //nothing to deregister
}

00246 - (void) synchroniseWithEnvironment
{
      //nothing to retrieve
}

00251 - (void) setEnvironment: (id) object
{
      [self deregisterWithEnvironment];
      object = environment;
      [self registerWithEnvironment];
}


/*******************

Public Methods

********************/

00265 - (void) translateBy: (Vector3D*) translationVector
{
      int i, k;

      if(isTranslationEnabled)
            for(i=0; i<gridPoints;i++)
                  for(k=0; k<3; k++)
                        grid->matrix[i][k] += translationVector->vector[k];
}

00275 - (void) setTranslationEnabled: (BOOL) value
{
      isTranslationEnabled = value;
}

- (BOOL) isTranslationEnabled
{
      return isTranslationEnabled;
}

00285 - (void) cavityDidMove
{
      int i;
      Vector3D translation, *newCentre;   

      newCentre = [cavity cavityCentre];
      for(i=0; i<3; i++)
      {
            translation.vector = newCentre->vector - cavityCentre.vector;
            cavityCentre.vector = newCentre->vector;
      }

      [self translateBy: &translation];
}

00300 - (void) resetCavity
{
      //free the last grid
      
      if(grid != NULL)
            [memoryManager freeMatrix: grid];

      [self _cavityInitialisation];
      [self _createGrid];
}

//Setting the cavity. The cavity is an object that conforms to the
//AdGridDelegate protocol. It is not retained. 

- (void) setCavity: (id) anObject
{
      if([anObject conformsToProtocol: @protocol(AdGridDelegate)])
            cavity = anObject;
      else
            [NSException raise: NSInvalidArgumentException
                  format: @"Delegate does not conform to AdGridDelegate protocol"];

      //free the last grid
      
      if(grid != NULL)
            [memoryManager freeMatrix: grid];

      [self _cavityInitialisation];
      [self _createGrid];
}


/*************

Accessors

**************/

//The grids delegate object

- (id) cavity
{
      return cavity;
}

- (id) grid
{
      return [NSValue valueWithPointer: grid];
}

- (NSArray*) spacing
{
      return [gridSpacing copy];
}

- (NSArray*) divisions
{
      NSWarnLog(@"Method %@ not implemented", NSStringFromSelector(_cmd));
      return nil;
}

- (int) numberOfPoints
{
      return grid->no_rows;
}

/****************

Coding

*****************/

- (id) initWithCoder: (NSCoder*) decoder
{
      int i, j, count;
      int rows, length; 
      double *buffer;
      Vector3D* centre;

      self = [super initWithCoder: decoder];    
      if([decoder allowsKeyedCoding])
      {     
            memoryManager = [AdMemoryManager appMemoryManager];
            rows = [decoder decodeIntForKey: @"Grid.Rows"];
            grid = [memoryManager allocateMatrixWithRows: rows withColumns: 3];
            cavity = [decoder decodeObjectForKey: @"Cavity"];
            isTranslationEnabled = [decoder decodeBoolForKey: @"TranslationEnabled"];
            gridSpacing = [[decoder decodeObjectForKey: @"GridSpacing"] retain];
            buffer = (double*)[decoder decodeBytesForKey: @"GridMatrix" returnedLength: &length];
            if(length != (int)sizeof(AdMatrixSize)*grid->no_rows*grid->no_columns)
                  [NSException raise: NSInternalInconsistencyException
                        format: @"Expected grid size and decoded grid size not equal"];

            for(count= 0, i=0; i< grid->no_rows; i++)
                  for(j=0; j<grid->no_columns; j++)
                  {
                        grid->matrix = buffer;
                        count++;
                  }

            gridPoints = grid->no_rows;
            //recalculate ticksPerAxis and cavityExtremes
            [self _cavityInitialisation];
            centre = [cavity cavityCentre];
            for(i=0; i<3; i++)
                  cavityCentre.vector[i] = centre->vector[i];

            environment = [AdEnvironment globalEnvironment];
            if(environment != nil)
            {
                  [self synchroniseWithEnvironment];
                  [self registerWithEnvironment];
            }
      }
      else
            [NSException raise: NSInvalidArgumentException
                  format: @"%@ class does not support non keyed coding", [self class]];

      return self;
}

- (void) encodeWithCoder: (NSCoder*) encoder
{
      int bytesLength;

      [super encodeWithCoder: encoder];
      if([encoder allowsKeyedCoding])
      {
            bytesLength = sizeof(AdMatrixSize)*grid->no_rows*grid->no_columns;      
            [encoder encodeBytes: (uint8_t*)grid->matrix length: bytesLength forKey: @"GridMatrix"];
            [encoder encodeInt: grid->no_rows forKey: @"Grid.Rows"];          
            [encoder encodeConditionalObject: cavity forKey: @"Cavity"];
            [encoder encodeBool: isTranslationEnabled forKey: @"TranslationEnabled"];
            [encoder encodeObject: gridSpacing forKey: @"GridSpacing"];
      }
      else
            [NSException raise: NSInvalidArgumentException
                  format: @"%@ class does not support non keyed coding", [self class]];
}

@end

Generated by  Doxygen 1.6.0   Back to index