summaryrefslogtreecommitdiffstats
path: root/hacks/glx/glschool_alg.c
diff options
context:
space:
mode:
Diffstat (limited to 'hacks/glx/glschool_alg.c')
-rw-r--r--hacks/glx/glschool_alg.c364
1 files changed, 0 insertions, 364 deletions
diff --git a/hacks/glx/glschool_alg.c b/hacks/glx/glschool_alg.c
deleted file mode 100644
index 09b9e6f..0000000
--- a/hacks/glx/glschool_alg.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/* school_alg.c, Copyright (c) 2005-2006 David C. Lambert <dcl@panix.com>
- *
- * Permission to use, copy, modify, distribute, and sell this software and its
- * documentation for any purpose is hereby granted without fee, provided that
- * the above copyright notice appear in all copies and that both that
- * copyright notice and this permission notice appear in supporting
- * documentation. No representations are made about the suitability of this
- * software for any purpose. It is provided "as is" without express or
- * implied warranty.
- */
-#include <math.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "yarandom.h"
-#include "glschool_alg.h"
-
-/* for xscreensaver */
-#undef drand48
-#define drand48() frand(1.0)
-
-#define RAD2DEG (180.0 / M_PI)
-
-
-static inline double
-norm(double *dv)
-{
- return sqrt(dv[0]*dv[0] + dv[1]*dv[1] + dv[2]*dv[2]);
-}
-
-
-static inline void
-addVector(double *v, double *d)
-{
- v[0] += d[0];
- v[1] += d[1];
- v[2] += d[2];
-}
-
-
-static inline void
-clearVector(double *v)
-{
- v[0] = v[1] = v[2] = 0.0;
-}
-
-
-static inline void
-scaleVector(double *v, double s)
-{
- v[0] *= s;
- v[1] *= s;
- v[2] *= s;
-}
-
-
-static inline void
-addScaledVector(double *v, double *d, double s)
-{
- v[0] += d[0]*s;
- v[1] += d[1]*s;
- v[2] += d[2]*s;
-}
-
-
-static inline void
-getDifferenceVector(double *v0, double *v1, double *diff)
-{
- diff[0] = v0[0] - v1[0];
- diff[1] = v0[1] - v1[1];
- diff[2] = v0[2] - v1[2];
-}
-
-
-void
-glschool_initFish(Fish *f, double *mins, double *ranges)
-{
- int i;
-
- for(i = 0; i < 3; i++) {
- FISH_IPOS(f, i) = mins[i] + drand48()*ranges[i];
- FISH_IACC(f, i) = 0.0;
- FISH_IVEL(f, i) = drand48();
- FISH_IMAGIC(f, i) = 0.70 + 0.60*drand48();
- FISH_IOLDVEL(f, i) = 0.0;
- }
-}
-
-
-void
-glschool_initFishes(School *s)
-{
- int i;
- Fish *f = (Fish *)0;
- int nFish = SCHOOL_NFISH(s);
- BBox *bbox = &SCHOOL_BBOX(s);
- double *mins = BBOX_MINS(bbox);
- double *ranges = SCHOOL_BBRANGES(s);
- Fish *theFishes = SCHOOL_FISHES(s);
-
- for(i = 0, f = theFishes; i < nFish; i++, f++)
- glschool_initFish(f, mins, ranges);
-}
-
-
-static void
-applyFishMovements(Fish *f, BBox *bbox, double minVel, double maxVel, double momentum)
-{
- int i;
- int oob = 0;
- double vMag = 0.0;
-
- for(i = 0; i < 3; i++) {
- double pos = FISH_IPOS(f, i);
- oob = (pos > BBOX_IMAX(bbox, i) || pos < BBOX_IMIN(bbox, i));
- if (oob == 0) FISH_IVEL(f, i) += FISH_IACC(f, i) * FISH_IMAGIC(f, i);
- vMag += (FISH_IVEL(f, i) * FISH_IVEL(f, i));
- }
- vMag = sqrt(vMag);
-
- if (vMag > maxVel)
- scaleVector(FISH_VEL(f), maxVel/vMag);
- else if (vMag < minVel)
- scaleVector(FISH_VEL(f), minVel/vMag);
-
- for(i = 0; i < 3; i++) {
- FISH_IVEL(f, i) = momentum * FISH_IOLDVEL(f, i) + (1.0-momentum) * FISH_IVEL(f, i);
- FISH_IPOS(f, i) += FISH_IVEL(f, i);
- FISH_IOLDVEL(f, i) = FISH_IVEL(f, i);
-
- if (FISH_IPOS(f, i) < BBOX_IMIN(bbox, i))
- FISH_IPOS(f, i) = BBOX_IMAX(bbox, i);
- else if (FISH_IPOS(f, i) > BBOX_IMAX(bbox, i))
- FISH_IPOS(f, i) = BBOX_IMIN(bbox, i);
- }
-}
-
-
-void
-glschool_applyMovements(School *s)
-{
- int i = 0;
- Fish *f = (Fish *)0;
- int nFish = SCHOOL_NFISH(s);
- double minVel = SCHOOL_MINVEL(s);
- double maxVel = SCHOOL_MAXVEL(s);
- double momentum = SCHOOL_MOMENTUM(s);
- BBox *bbox = &SCHOOL_BBOX(s);
- Fish *theFishes = SCHOOL_FISHES(s);
-
- for(i = 0, f = theFishes; i < nFish; i++, f++)
- applyFishMovements(f, bbox, minVel, maxVel, momentum);
-}
-
-
-School *
-glschool_initSchool(int nFish, double accLimit, double maxV, double minV, double distExp, double momentum,
- double minRadius, double avoidFact, double matchFact, double centerFact, double targetFact,
- double distComp)
-{
- School *s = (School *)0;
-
- if ((s = (School *)malloc(sizeof(School))) == (School *)0) {
- perror("initSchool School allocation failed: ");
- return s;
- }
-
- if ((SCHOOL_FISHES(s) = (Fish *)malloc(sizeof(Fish)*nFish)) == (Fish *)0) {
- perror("initSchool Fish array allocation failed: ");
- free(s);
- return (School *)0;
- }
-
- SCHOOL_NFISH(s) = nFish;
- SCHOOL_ACCLIMIT(s) = accLimit;
- SCHOOL_MAXVEL(s) = maxV;
- SCHOOL_MINVEL(s) = minV;
- SCHOOL_DISTEXP(s) = distExp;
- SCHOOL_MOMENTUM(s) = momentum;
- SCHOOL_MINRADIUS(s) = minRadius;
- SCHOOL_MINRADIUSEXP(s) = pow(minRadius, distExp);
- SCHOOL_MATCHFACT(s) = matchFact;
- SCHOOL_AVOIDFACT(s) = avoidFact;
- SCHOOL_CENTERFACT(s) = centerFact;
- SCHOOL_TARGETFACT(s) = targetFact;
- SCHOOL_DISTCOMP(s) = distComp;
-
- return s;
-}
-
-void
-glschool_freeSchool(School *s)
-{
- free(SCHOOL_FISHES(s));
- free(s);
-}
-
-void
-glschool_setBBox(School *s, double xMin, double xMax, double yMin, double yMax, double zMin, double zMax)
-{
- int i;
- BBox *bbox = &SCHOOL_BBOX(s);
-
- BBOX_XMIN(bbox) = xMin; BBOX_XMAX(bbox) = xMax;
- BBOX_YMIN(bbox) = yMin; BBOX_YMAX(bbox) = yMax;
- BBOX_ZMIN(bbox) = zMin; BBOX_ZMAX(bbox) = zMax;
-
- for(i = 0; i < 3; i++) {
- SCHOOL_IMID(s, i) = BBOX_IMID(bbox, i);
- SCHOOL_IRANGE(s, i) = BBOX_IRANGE(bbox, i);
- }
-}
-
-
-void
-glschool_newGoal(School *s)
-{
- SCHOOL_IGOAL(s,0) = 0.85*(drand48()-0.5)*SCHOOL_IRANGE(s,0) + SCHOOL_IMID(s,0);
- SCHOOL_IGOAL(s,1) = 0.40*(drand48()-0.5)*SCHOOL_IRANGE(s,1) + SCHOOL_IMID(s,1);
- SCHOOL_IGOAL(s,2) = 0.85*(drand48()-0.5)*SCHOOL_IRANGE(s,2) + SCHOOL_IMID(s,2);
-}
-
-
-double
-glschool_computeNormalAndThetaToPlusZ(double *v, double *xV)
-{
- double x1 = 0.0;
- double y1 = 0.0;
- double z1 = 1.0;
- double x2 = v[0];
- double y2 = v[1];
- double z2 = v[2];
- double theta = 0.0;
- double xVNorm = 0.0;
- double sinTheta = 0.0;
- double v2Norm = norm(v);
-
- if (v2Norm == 0.0) {
- xV[1] = 1.0;
- xV[0] = xV[2] = 0.0;
- return theta;
- }
- xV[0] = (y1*z2 - z1*y2);
- xV[1] = -(x1*z2 - z1*x2);
- xV[2] = (x1*y2 - y1*x2);
- xVNorm = norm(xV);
-
- sinTheta = xVNorm/v2Norm;
- return (asin(sinTheta) * RAD2DEG);
-}
-
-
-int
-glschool_computeGroupVectors(School *s, Fish *ref, double *avoidance, double *centroid, double *avgVel)
-{
- int i;
- double dist;
- double adjDist;
- double diffVect[3];
- int neighborCount = 0;
- Fish *test = (Fish *)0;
- int nFish = SCHOOL_NFISH(s);
- double distExp = SCHOOL_DISTEXP(s);
- double distComp = SCHOOL_DISTCOMP(s);
- double minRadiusExp = SCHOOL_MINRADIUSEXP(s);
- Fish *fishes = SCHOOL_FISHES(s);
-
- for(i = 0, test = fishes; i < nFish; i++, test++) {
- if (test == ref) continue;
-
- getDifferenceVector(FISH_POS(ref), FISH_POS(test), diffVect);
-
- dist = norm(diffVect) - distComp;
- if (dist < 0.0) dist = 0.1;
-
- adjDist = pow(dist, distExp);
- if (adjDist > minRadiusExp) continue;
-
- neighborCount++;
-
- addVector(avgVel, FISH_VEL(test));
- addVector(centroid, FISH_POS(test));
-
- addScaledVector(avoidance, diffVect, 1.0/adjDist);
- }
- if (neighborCount > 0) {
- scaleVector(avgVel, 1.0/neighborCount);
- scaleVector(centroid, 1.0/neighborCount);
- }
- return neighborCount;
-}
-
-
-void
-glschool_computeAccelerations(School *s)
-{
- int i;
- int j;
- int neighborCount;
- double dist;
- double adjDist;
- double accMag;
- double avgVel[3];
- double diffVect[3];
- double centroid[3];
- double avoidance[3];
- Fish *ref = (Fish *)0;
- int nFish = SCHOOL_NFISH(s);
- double *goal = SCHOOL_GOAL(s);
- double distExp = SCHOOL_DISTEXP(s);
- double distComp = SCHOOL_DISTCOMP(s);
- double avoidFact = SCHOOL_AVOIDFACT(s);
- double matchFact = SCHOOL_MATCHFACT(s);
- double centerFact = SCHOOL_CENTERFACT(s);
- double targetFact = SCHOOL_TARGETFACT(s);
- double accLimit = SCHOOL_ACCLIMIT(s);
- double minRadius = SCHOOL_MINRADIUS(s);
- Fish *fishes = SCHOOL_FISHES(s);
-
- for(i = 0, ref = fishes; i < nFish; i++, ref++) {
- clearVector(avgVel);
- clearVector(centroid);
- clearVector(avoidance);
- clearVector(FISH_ACC(ref));
- neighborCount = glschool_computeGroupVectors(s, ref, avoidance, centroid, avgVel);
-
- /* avoidanceAccel[] = avoidance[] * AvoidFact */
- scaleVector(avoidance, avoidFact);
- addVector(FISH_ACC(ref), avoidance);
-
- accMag = norm(FISH_ACC(ref));
- if (neighborCount > 0 && accMag < accLimit) {
- for(j = 0; j < 3; j++) {
- FISH_IAVGVEL(ref, j) = avgVel[j];
- FISH_IACC(ref, j) += ((avgVel[j] - FISH_IVEL(ref, j)) * matchFact);
- }
-
- accMag = norm(FISH_ACC(ref));
- if (accMag < accLimit) {
- for(j = 0; j < 3; j++)
- FISH_IACC(ref, j) += ((centroid[j] - FISH_IPOS(ref, j)) * centerFact);
- }
- }
-
- accMag = norm(FISH_ACC(ref));
- if (accMag < accLimit) {
- getDifferenceVector(goal, FISH_POS(ref), diffVect);
-
- dist = norm(diffVect) - distComp;
- if (dist < 0.0) dist = 0.1;
-
- /*adjDist = pow(dist, distExp);*/
- if (dist > minRadius) {
- adjDist = pow(dist, distExp);
- for(j = 0; j < 3; j++)
- FISH_IACC(ref, j) += (diffVect[j]*targetFact/adjDist);
- }
- }
- }
-}