43 m_bounds(std::make_shared<const
ConeBounds>(alpha, symmetric)) {}
46 double zmin,
double zmax,
double halfPhi)
49 m_bounds(std::make_shared<const
ConeBounds>(alpha, zmin, zmax, halfPhi)) {
53 std::shared_ptr<const ConeBounds> cbounds)
60 const Vector3& sfCenter = center(gctx);
64 return Vector3(sfCenter.x() +
bounds().r(sfCenter.z()), sfCenter.y(),
86 return transform(gctx).matrix().block<3, 1>(0, 2);
95 Vector3 measY = rotSymmetryAxis(gctx);
97 Vector3 measDepth =
Vector3(position.x(), position.y(), 0.).normalized();
101 mFrame.col(0) = measX;
102 mFrame.col(1) = measY;
103 mFrame.col(2) = measDepth;
124 double r = loc3Dframe.z() *
bounds().tanAlpha();
125 if (std::abs(
perp(loc3Dframe) - r) > tolerance) {
129 Vector2(r * atan2(loc3Dframe.y(), loc3Dframe.x()), loc3Dframe.z()));
134 const Vector3& direction)
const {
138 double sgn = posLocal.z() > 0. ? -1. : +1.;
141 Vector3 normalC(cos(phi) * cosAlpha, sin(phi) * cosAlpha, sgn * sinAlpha);
144 double cAlpha = normalC.dot(direction);
145 return std::abs(1. / cAlpha);
149 return "Acts::ConeSurface";
157 sgn = lposition[Acts::eBoundLoc1] > 0 ? -1. : +1.;
160 Vector3 localNormal(cos(phi) * cosAlpha, sin(phi) * cosAlpha, sgn * sinAlpha);
170 return pos3D.normalized();
175 return (*m_bounds.get());
182 std::vector<Polyhedron::FaceType> faces;
183 std::vector<Polyhedron::FaceType> triangularMesh;
188 if (minZ == -std::numeric_limits<double>::infinity() or
189 maxZ == std::numeric_limits<double>::infinity()) {
190 throw std::domain_error(
191 "Polyhedron repr of boundless surface not possible");
197 bool tipExists =
false;
199 vertices.push_back(ctransform *
Vector3(0., 0., 0.));
206 bool fullCone = (hPhiSec == M_PI);
211 avgPhi - hPhiSec, avgPhi + hPhiSec,
215 std::vector<double> coneSides;
217 coneSides.push_back(minZ);
220 coneSides.push_back(maxZ);
222 for (
auto&
z : coneSides) {
224 size_t firstIv = vertices.size();
226 double r = std::abs(
z) *
bounds().tanAlpha();
228 for (
unsigned int iseg = 0; iseg < phiSegs.size() - 1; ++iseg) {
229 int addon = (iseg == phiSegs.size() - 2 and not fullCone) ? 1 : 0;
231 phiSegs[iseg + 1], lseg, addon,
232 zoffset, ctransform);
236 for (
size_t iv = firstIv + 2; iv < vertices.size() + 1; ++iv) {
237 size_t one = 0, two = iv - 1, three = iv - 2;
241 faces.push_back({one, two, three});
246 faces.push_back({0, firstIv, vertices.size() - 1});
248 faces.push_back({0, vertices.size() - 1, firstIv});
255 triangularMesh = faces;
259 faces = facesMesh.first;
260 triangularMesh = facesMesh.second;
262 return Polyhedron(vertices, faces, triangularMesh,
false);
267 const Vector3& direction)
const {
271 Vector3 dir1 = invTrans.linear() * direction;
274 double tan2Alpha =
bounds().tanAlpha() *
bounds().tanAlpha(),
275 A = dir1.x() * dir1.x() + dir1.y() * dir1.y() -
276 tan2Alpha * dir1.z() * dir1.z(),
277 B = 2 * (dir1.x() * point1.x() + dir1.y() * point1.y() -
278 tan2Alpha * dir1.z() * point1.z()),
279 C = point1.x() * point1.x() + point1.y() * point1.y() -
280 tan2Alpha * point1.z() * point1.z();
293 auto qe = intersectionSolver(gctx, position, direction);
296 if (qe.solutions == 0) {
301 Vector3 solution1 = position + qe.first * direction;
303 ? Intersection3D::Status::onSurface
304 : Intersection3D::Status::reachable;
306 if (bcheck and not isOnSurface(gctx, solution1, direction, bcheck)) {
307 status1 = Intersection3D::Status::missed;
311 Vector3 solution2 = position + qe.first * direction;
313 ? Intersection3D::Status::onSurface
314 : Intersection3D::Status::reachable;
315 if (bcheck and not isOnSurface(gctx, solution2, direction, bcheck)) {
316 status2 = Intersection3D::Status::missed;
325 return {{first, second},
this};
327 return {{second, first},
this};
335 const auto direction = parameters.segment<3>(
eFreeDir0);
337 const auto pcRowVec = (
position - center(gctx)).transpose().eval();
339 const auto& rotation =
transform(gctx).rotation();
341 const auto& localXAxis = rotation.col(0);
342 const auto& localYAxis = rotation.col(1);
343 const auto& localZAxis = rotation.col(2);
345 const auto localPos = (rotation.transpose() *
position).eval();
346 const auto dx = direction.dot(localXAxis);
347 const auto dy = direction.dot(localYAxis);
348 const auto dz = direction.dot(localZAxis);
350 const auto tanAlpha2 =
bounds().tanAlpha() *
bounds().tanAlpha();
351 const auto norm = 1 / (1 -
dz *
dz * (1 + tanAlpha2));
353 const auto& dirRowVec = direction.transpose();
357 const auto localXAxisToPath =
358 (-2 *
norm * (dx * pcRowVec + localPos.x() * dirRowVec)).eval();
359 const auto localYAxisToPath =
360 (-2 *
norm * (
dy * pcRowVec + localPos.y() * dirRowVec)).eval();
361 const auto localZAxisToPath =
362 (2 *
norm * tanAlpha2 * (
dz * pcRowVec + localPos.z() * dirRowVec) -
364 (dx * localPos.x() +
dy * localPos.y() -
365 dz * localPos.z() * tanAlpha2) *
369 const auto [rotToLocalXAxis, rotToLocalYAxis, rotToLocalZAxis] =
375 2 *
norm * (dx * localXAxis.transpose() +
dy * localYAxis.transpose());
377 localXAxisToPath * rotToLocalXAxis + localYAxisToPath * rotToLocalYAxis +
378 localZAxisToPath * rotToLocalZAxis;
391 const double lr =
perp(localPos);
392 const double lphi =
phi(localPos);
393 const double lcphi = std::cos(lphi);
394 const double lsphi = std::sin(lphi);
396 const double R = localPos.z() *
bounds().tanAlpha();
398 loc3DToLocBound << -R * lsphi / lr, R * lcphi / lr,
399 lphi *
bounds().tanAlpha(), 0, 0, 1;
401 return loc3DToLocBound;