/* Copyright 1999-2008 ImageMagick Studio LLC, a non-profit organization dedicated to making software imaging solutions freely available. You may not use this file except in compliance with the License. obtain a copy of the License at http://www.imagemagick.org/script/license.php Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. MagickCore methods to interactively animate an image sequence. */ #ifdef hpux #define _HPUX_SOURCE 1 #endif #include #include #include #if defined(__STDC__) || defined(sgi) || defined(_AIX) #include #else #include #include #endif #include #include #include #include /* Define declarations for the N-body program. */ #ifdef WIN32 #undef stderr #define stderr stdout #endif #define AbsoluteValue(x) ((x) < 0 ? -(x) : (x)) #ifndef False #define False 0 #endif #define CircumscribedSphereRadius 1.5 /* choose from: 3.0, 2.5, 2.0, 1.5 */ #define GravitationalConstant 1.0e-3 #define HighestDegreeHarmonic 20 #define Max(x,y) (((x) > (y)) ? (x) : (y)) #define MaxChildren 8 #define MaxNodesInteractiveField 189 /* choose from: 140, 119, 77, 56 */ #define MaxNodesNearField 26 /* choose from: 80, 56, 32, 26 */ #define MaxTreeDepth 8 /* Log2(MaxRange) */ #define Min(x,y) (((x) < (y)) ? (x) : (y)) #define NodesInAQueue 4681 /* 1+8+64+512+4096 */ #ifndef RAND_MAX #define RAND_MAX 32767 #endif #define TetrahedralArray(array,i,j,k) \ array[cube.tetra_three[i]-cube.tetra_two[(i)+(j)]+(k)] #ifndef True #define True 1 #endif #define Warning(message,qualifier) \ { \ (void) fprintf(stderr,"%s: %s",application_name,message); \ if (qualifier != (char *) NULL) \ (void) fprintf(stderr," (%s)",qualifier); \ (void) fprintf(stderr,".\n"); \ } /* Structures. */ typedef struct _Particle { float x, y, z; struct _Particle *next; } Particle; typedef struct _Node { struct _Node *parent, *child[MaxChildren], *near_field[MaxNodesNearField+1], *interactive_field[MaxNodesInteractiveField+8]; unsigned long id, level; float mid_x, mid_y, mid_z, *phi, *psi; Particle *particle; } Node; typedef struct _Nodes { Node nodes[NodesInAQueue]; float *phi, *psi; struct _Nodes *next; } Nodes; typedef struct _Cube { Node *root; unsigned long depth; long level; Node **near_neighbor; unsigned long nodes, free_nodes; Node *next_node; Nodes *node_queue; float edge_length[MaxTreeDepth], diagonal_length[MaxTreeDepth], binomial[HighestDegreeHarmonic+1][HighestDegreeHarmonic+1], one_power[HighestDegreeHarmonic+1], x_power[HighestDegreeHarmonic+1], y_power[HighestDegreeHarmonic+1], z_power[HighestDegreeHarmonic+1]; unsigned long tetra_two[HighestDegreeHarmonic+3], tetra_three[HighestDegreeHarmonic+3], precision, coefficients; float *ijk_binomial, *ijk_factorial, *phi, *phi_tilde, *psi, *psi_tilde; double near_potential, far_potential; } Cube; /* Variable declarations. */ char *application_name; /* Forward declarations. */ static double MultipolePotential(Particle *,unsigned long,unsigned long,unsigned long, double,double), NaivePotential(Particle *,unsigned long); static long ProcessTime(void); static Node *InitializeNode(unsigned long,unsigned long,Node *,double,double,double); static unsigned long Binomial(long,long), InNearField(register Node *,register Node *); static void Classification(Particle *,unsigned long), ComputePhi(register Node *), ComputePsi(register Node *), CreateCube(register Node *), DefineInteractiveField(register Node *), DefineNearField(register Node *), Error(char *,char *), EvaluatePotential(Node *node), FindNeighbors(register Node *,register Node *), LocalExpansion(Node *, Node *,float *), MultipoleExpansion(Node *,Node *,register float *);