Files
geant4/source/visualization/modeling/src/G4BoundingSphereScene.cc
T
2016-06-09 10:49:58 +02:00

117 lines
4.1 KiB
C++

//
// ********************************************************************
// * DISCLAIMER *
// * *
// * The following disclaimer summarizes all the specific disclaimers *
// * of contributors to this software. The specific disclaimers,which *
// * govern, are listed with their locations in: *
// * http://cern.ch/geant4/license *
// * *
// * Neither the authors of this software system, nor their employing *
// * institutes,nor the agencies providing financial support for this *
// * work make any representation or warranty, express or implied, *
// * regarding this software system or assume any liability for its *
// * use. *
// * *
// * This code implementation is the intellectual property of the *
// * GEANT4 collaboration. *
// * By copying, distributing or modifying the Program (or any work *
// * based on the Program) you indicate your acceptance of this *
// * statement, and all its terms. *
// ********************************************************************
//
//
// $Id: G4BoundingSphereScene.cc,v 1.8 2001/07/25 21:10:22 johna Exp $
// GEANT4 tag $Name: geant4-05-02-patch-01 $
//
//
// John Allison 7th June 1997
// An artificial scene to reuse G4VScene code to calculate a bounding sphere.
#include "G4BoundingSphereScene.hh"
#include "G4VSolid.hh"
#include "G4PhysicalVolumeModel.hh"
#include "G4Vector3D.hh"
G4BoundingSphereScene::G4BoundingSphereScene (G4VModel* pModel):
fpModel (pModel),
fRadius (-1.),
fpObjectTransformation (0)
{}
G4BoundingSphereScene::~G4BoundingSphereScene () {}
void G4BoundingSphereScene::PreAddThis
(const G4Transform3D& objectTransformation,
const G4VisAttributes&) {
fpObjectTransformation = &objectTransformation;
}
G4VisExtent G4BoundingSphereScene::GetBoundingSphereExtent () {
return G4VisExtent (fCentre, fRadius);
}
void G4BoundingSphereScene::Accrue (const G4VSolid& solid) {
const G4VisExtent& newExtent = solid.GetExtent ();
G4Point3D newCentre = newExtent.GetExtentCentre ();
if (fpObjectTransformation) {
newCentre.transform (*fpObjectTransformation);
}
const G4double newRadius = newExtent.GetExtentRadius ();
AccrueBoundingSphere (newCentre, newRadius);
// Curtail descent - can assume daughters are contained within mother...
G4PhysicalVolumeModel* pPVM = fpModel->GetG4PhysicalVolumeModel();
if (pPVM) pPVM->CurtailDescent();
}
void G4BoundingSphereScene::ResetBoundingSphere () {
fCentre = G4Point3D ();
fRadius = -1.;
fpObjectTransformation = 0;
}
void G4BoundingSphereScene::AccrueBoundingSphere
(const G4Point3D& newCentre,
G4double newRadius) {
if (fRadius < 0 ) { // First time.
fCentre = newCentre;
fRadius = newRadius;
}
else {
G4Vector3D join = newCentre - fCentre;
if (join == G4Vector3D (0., 0., 0.)) { // Centres coincide.
if (fRadius < newRadius) fRadius = newRadius;
}
else if (join.mag () + newRadius <= fRadius) { // Inside accrued sphere.
// Do nothing.
}
else {
G4Vector3D unitJoin = join.unit ();
G4Point3D oldExtremity1 = fCentre - fRadius * unitJoin;
G4Point3D newExtremity1 = newCentre - newRadius * unitJoin;
G4Point3D oldExtremity2 = fCentre + fRadius * unitJoin;
G4Point3D newExtremity2 = newCentre + newRadius * unitJoin;
G4Point3D extremity1;
if (oldExtremity1 * unitJoin < newExtremity1 * unitJoin) {
extremity1 = oldExtremity1;
}
else {
extremity1 = newExtremity1;
}
G4Point3D extremity2;
if (oldExtremity2 * unitJoin > newExtremity2 * unitJoin) {
extremity2 = oldExtremity2;
}
else {
extremity2 = newExtremity2;
}
fCentre = 0.5 * (extremity2 + extremity1);
fRadius = 0.5 * (extremity2 - extremity1).mag ();
}
}
}