@@ -180,15 +180,23 @@ bool CIESProfileParser::parse(CIESProfile& result)
180180 float totalEmissionIntegral = 0.0 , nonZeroEmissionDomainSize = 0.0 ;
181181 constexpr auto FULL_SOLID_ANGLE = 4 .0f * core::PI<float >();
182182
183+ // TODO: this code could have two separate inner for loops for `result.symmetry != CIESProfile::ISOTROPIC` cases
183184 const auto H_ANGLES_I_RANGE = result.symmetry != CIESProfile::ISOTROPIC ? result.hAngles .size () - 1 : 1 ;
184185 const auto V_ANGLES_I_RANGE = result.vAngles .size () - 1 ;
185186
186- for (size_t i = 0 ; i < H_ANGLES_I_RANGE; i ++)
187+ for (size_t j = 0 ; j < V_ANGLES_I_RANGE; j ++)
187188 {
188- const float dPhiRad = result.symmetry != CIESProfile::ISOTROPIC ? (hAngles[i + 1 ] - hAngles[i]) : core::PI<float >() * 2 .0f ;
189-
190- for (size_t j = 0 ; j < V_ANGLES_I_RANGE; j++)
189+ const float thetaRad = core::radians<float >(result.vAngles [j]);
190+ const float cosLo = std::cos (thetaRad);
191+ const float cosHi = std::cos (core::radians<float >(result.vAngles [j+1 ]));
192+ const float dsinTheta = cosLo - cosHi;
193+
194+ float stripIntegral = 0 .f ;
195+ float nonZeroStripDomain = 0 .f ;
196+ for (size_t i = 0 ; i < H_ANGLES_I_RANGE; i++)
191197 {
198+ const float dPhiRad = result.symmetry != CIESProfile::ISOTROPIC ? core::radians<float >(hAngles[i + 1 ] - hAngles[i]) : (core::PI<float >() * 2 .0f );
199+
192200 const auto candelaValue = result.getCandelaValue (i, j);
193201
194202 // interpolate candela value spanned onto a solid angle
@@ -199,23 +207,17 @@ bool CIESProfileParser::parse(CIESProfile& result)
199207 if (result.maxCandelaValue < candelaValue)
200208 result.maxCandelaValue = candelaValue;
201209
202- const float thetaRad = core::radians<float >(result.vAngles [j]);
203- const float cosLo = std::cos (core::radians<float >(result.vAngles [j]));
204- const float cosHi = std::cos (core::radians<float >(result.vAngles [j + 1 ]));
205-
206- const auto differentialSolidAngle = dPhiRad*(cosLo - cosHi);
207- const auto integralV = candelaAverage * differentialSolidAngle;
208-
209- if (integralV > 0.0 )
210- {
211- totalEmissionIntegral += integralV;
212- nonZeroEmissionDomainSize += differentialSolidAngle;
213- }
210+ stripIntegral += candelaAverage*dPhiRad;
211+ if (candelaAverage>0 .f )
212+ nonZeroStripDomain += dPhiRad;
214213 }
214+ totalEmissionIntegral += stripIntegral*dsinTheta;
215+ nonZeroEmissionDomainSize += nonZeroStripDomain*dsinTheta;
215216 }
216217
217- nonZeroEmissionDomainSize = std::clamp<float >(nonZeroEmissionDomainSize, 0.0 , FULL_SOLID_ANGLE);
218- if (nonZeroEmissionDomainSize <= 0 ) // protect us from division by 0 (just in case, we should never hit it)
218+ assert (nonZeroEmissionDomainSize >= 0 .f );
219+ // assert(nonZeroEmissionDomainSize*fluxMultiplier =approx= 2.f*(cosBack-cosFront)*PI);
220+ if (nonZeroEmissionDomainSize <= std::numeric_limits<float >::min ()) // protect us from division by small numbers (just in case, we should never hit it)
219221 return false ;
220222
221223 result.avgEmmision = totalEmissionIntegral / static_cast <decltype (totalEmissionIntegral)>(nonZeroEmissionDomainSize);
0 commit comments