@@ -49,14 +49,37 @@ void ChipSimResponse::computeCentreFromData()
4949 qVec.push_back (p.second );
5050 }
5151
52- float intQ = 0 .f , intZQ = 0 .f ;
52+ struct BinInfo { float z0, z1, q0, q1, dq; };
53+ std::vector<BinInfo> bins;
54+ float totQ = 0 .f ;
5355 for (size_t i = 0 ; i + 1 < zVec.size (); ++i) {
5456 float z0 = zVec[i], z1 = zVec[i + 1 ];
5557 float q0 = qVec[i], q1 = qVec[i + 1 ];
5658 float dz = z1 - z0;
57- intQ += 0 .5f * (q0 + q1) * dz;
58- intZQ += 0 .5f * (z0 * q0 + z1 * q1) * dz;
59+ float dq = 0 .5f * (q0 + q1) * dz;
60+ bins.push_back ({z0, z1, q0, q1, dq});
61+ totQ += dq;
5962 }
63+ if (totQ <= 0 .f ) { mRespCentreDep = 0 .f ; return ; }
6064
61- mRespCentreDep = (intQ > 0 .f ) ? intZQ / intQ : 0 .f ;
65+ float halfQ = 0 .5f * totQ;
66+ float cumQ = 0 .f ;
67+ for (const auto & b : bins) {
68+ if (cumQ + b.dq < halfQ) { cumQ += b.dq ; continue ; }
69+ float qSlope = (b.q1 - b.q0 ) / (b.z1 - b.z0 );
70+ float dz = b.z1 - b.z0 ;
71+ float A = qSlope * 0 .5f ;
72+ float B = b.q0 ;
73+ float C = cumQ - halfQ;
74+ float disc = B * B - 4 .f * A * C;
75+ float x;
76+ if (disc >= 0 .f && std::abs (A) > 1 .e -12f )
77+ x = (-B + std::sqrt (disc)) / (2 .f * A);
78+ else
79+ x = (halfQ - cumQ) / b.q0 ;
80+ x = std::clamp (x, 0 .f , dz);
81+ mRespCentreDep = b.z0 + x;
82+ return ;
83+ }
84+ mRespCentreDep = mDptMax ;
6285}
0 commit comments