#include #include "potential.h" #include "scene.h" #include "Common.h" #include "PatchProbabilityAssigner.h" PatchProbabilityAssigner::PatchProbabilityAssigner() { numpatches = 0; sum = 0.0; pa = NULL; pb = NULL; } PatchProbabilityAssigner::~PatchProbabilityAssigner() { freeProbabilities(); } int PatchProbabilityAssigner::assignProbabilities(PATCH *patch) { // Alloc arrays ... if (allocProbabilities()) { // Use derived classes computations recomputeProbabilities(patch); // Normalise so that numbers in pb[] becomes trues probabilities. // sum = 1, and always between 0 and 1. normalizeProbabilities(); return 1; } return 0; } double PatchProbabilityAssigner::getProbability(const int pid) { return pb[pid]; } double PatchProbabilityAssigner::getProbability(const PATCH *patch) { return pb[patch->id]; } int PatchProbabilityAssigner::choosePatchId() { int m; double rn; // Choose a patch according to probability array. rn = drand48(); m = 1; while (m < numpatches) { if (rn <= pb[m]) break; rn -= pb[m]; m++; } // Numeric errors are possible... if (m==numpatches) m--; return m; } PATCH* PatchProbabilityAssigner::choosePatch() { return pa[choosePatchId()]; } void PatchProbabilityAssigner::normalizeProbabilities() { int i; // If everything is zero, fall back to simple area sampling ... if (sum==0.0) { printf("Probability assignment failed !\nFalling back to simple pure area sampling.\n"); for(i=1;iarea; sum += pb[i]; } } // Multiplication is faster than division on most computers sum = 1.0 / sum; // Normalize for(i=1;iarea; sum += pb[i]; } } // ----------------------------------------------- DirectPotentialPatchProbabilityAssigner implementation void DirectPotentialPatchProbabilityAssigner::recomputeProbabilities(PATCH*) { int i; // Other modules of renderpark are doing it... UpdateDirectPotential(); sum = 0.0; for (i=1;idirect_potential; sum += pb[i]; } } // ----------------------------------------------- EquiWinPatchProbabilityAssigner implementation void EquiWinPatchProbabilityAssigner::recomputeProbabilities(PATCH*) { double hmin,htmp; int nhit,i; // Find minimum window size hmin = -1.0; for (i=1;igetNumberOfImpacts(i-1); // If the patch receive no particle htmp is infinite, so we skip this one if (nhit>0) { htmp = sqrt((pa[i]->area*deState.c1)/((double)nhit)); if ((htmparea) - deState.isp->getNumberOfImpacts(i-1); sum += pb[i]; } } // ----------------------------------------------- CombinePatchProbabilityAssigner implementation CombinePatchProbabilityAssigner::CombinePatchProbabilityAssigner(PatchProbabilityAssigner *nppa1,PatchProbabilityAssigner *nppa2) { // Save ppa1 = nppa1; ppa2 = nppa2; } CombinePatchProbabilityAssigner::~CombinePatchProbabilityAssigner() { delete ppa1; delete ppa2; } void CombinePatchProbabilityAssigner::recomputeProbabilities(PATCH* p) { int i; // Compute ... ppa1->assignProbabilities(p); ppa2->assignProbabilities(p); // Combine ... sum = 0.0; for(i=1;igetProbability(i) * ppa2->getProbability(i); sum += pb[i]; } }