home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * Distribute N points in a one/two dimensional domain, so as to minimize *
- * their energy according to a given energy function. *
- * *
- * Written by Gershon Elber, February 1994 *
- ******************************************************************************/
-
- #include <math.h>
- #include "irit_sm.h"
- #include "imalloc.h"
- #include "dist_pts.h"
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Distributes N points with a given energy in the region in the X line that M
- * is bounded by XMin, XMax. M
- * Energy is specified via the EnergyFunc that recieves the X location. M
- * Resolution * N specifies how many samples to take from EnergyFunc. M
- * Returns an array of N distributed points. M
- * The solution to the distribution is analythic provided EnergyFunc can be M
- * integrated. Herein, this integral is computed nomerically. M
- * *
- * PARAMETERS: M
- * N: Number of points to distribute, M
- * XMin: Minimum of domain to distribute points. M
- * XMax: Minimum of domain to distribute points. M
- * Resolution: Fineness of integral calculation. M
- * EnergyFunc: Energy function to use. M
- * *
- * RETURN VALUE: M
- * RealType *: A vector of N points distributed as requested. M
- * *
- * KEYWORDS: M
- * DistPoint1DWithEnergy, point distribution M
- *****************************************************************************/
- RealType *DistPoint1DWithEnergy(int N,
- RealType XMin,
- RealType XMax,
- int Resolution,
- DistEnergy1DFuncType EnergyFunc)
- {
- int i, j,
- IntegN = N * Resolution;
- RealType X, *R, IntegMaxVal, IntegDelta, IntegVal, Dx, DxN, *Integ, *Dist;
-
- if (N < 2)
- IritFatalError("DistPoint1DWithEnergy: N must be at least 2.");
-
- N = N < 2 ? 2 : N,
- IntegN = N * Resolution;
- Dx = XMax - XMin;
- DxN = Dx / IntegN;
- Integ = (RealType *) IritMalloc((IntegN + 2) * sizeof(RealType));
- Dist = (RealType *) IritMalloc(N * sizeof(RealType));
-
- /* Compute first order approximation of the integral of energy function. */
- Integ[0] = 0.0;
- for (i = 1, R = &Integ[1], X = XMin + DxN / 2;
- i < IntegN + 2;
- i++, R++, X += DxN) {
- RealType
- E = EnergyFunc(X);
-
- *R = R[-1] + MAX(E, 0.0); /* Do not allow negative energy... */
- }
-
- if ((IntegMaxVal = Integ[IntegN]) < EPSILON) {
- /* No real energy in the data. Apply uniform distribution. */
- for (i = 1, R = &Integ[1]; i < IntegN + 2; i++)
- *R++ = i;
- IntegMaxVal = Integ[IntegN];
- }
-
- IntegDelta = IntegMaxVal / (N - 1);
- IntegVal = 0.0;
-
- /* Copy the points to the returned data structure. */
- for (i = 0, j = 0; i < N; i++) {
- while (IntegVal >= Integ[j])
- j++;
- X = j - 1 + (IntegVal - Integ[j - 1]) / (Integ[j] - Integ[j - 1]);
- IntegVal += IntegDelta;
-
- Dist[i] = XMin + Dx * X / IntegN;
- }
-
- IritFree((VoidPtr) Integ);
-
- return Dist;
- }
-