Files
geant4/source/geometry/solids/BREPS/src/G4BSplineCurve.cc
T
2016-06-09 11:11:55 +02:00

334 lines
8.9 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: G4BSplineCurve.cc,v 1.11 2003/10/28 13:42:30 gcosmo Exp $
// GEANT4 tag $Name: geant4-07-00-cand-01 $
//
// ----------------------------------------------------------------------
// GEANT 4 class source file
//
// G4BSplineCurve.cc
//
// ----------------------------------------------------------------------
#include "G4BSplineCurve.hh"
#include "G4ControlPoints.hh"
#include "G4KnotVector.hh"
G4BSplineCurve::G4BSplineCurve()
: degree(0), controlPointsList(0), knots(0), weightsData(0)
{
}
void G4BSplineCurve::Init(G4int degree0, G4Point3DVector* controlPointsList0,
G4doubleVector* knots0,
G4doubleVector* weightsData0)
{
degree= degree0;
G4int nbpoints = controlPointsList0->size();
controlPointsList = new G4Point3DVector(nbpoints,G4Point3D(0,0,0));
G4int a;
for(a = 0; a < nbpoints; a++)
{
(*controlPointsList)[a] = (*controlPointsList0)[a];
}
G4int nbknots = knots0->size();
knots = new G4doubleVector(nbknots,0.);
for(a = 0; a < nbknots; a++)
{
(*knots)[a] = (*knots0)[a];
}
G4int nbweights = weightsData0->size();
weightsData = new G4doubleVector(nbweights,0.);
for(a = 0; a < nbweights; a++)
{
(*weightsData)[a] = (*weightsData0)[a];
}
SetBounds((*knots)[0], (*knots)[knots->size()-1]);
}
G4BSplineCurve::~G4BSplineCurve()
{
delete [] controlPointsList;
delete [] knots;
delete [] weightsData;
}
G4BSplineCurve::G4BSplineCurve(const G4BSplineCurve& right)
: G4Curve()
{
delete [] controlPointsList;
delete [] knots;
delete [] weightsData;
Init(right.degree, right.controlPointsList,
right.knots, right.weightsData);
bBox = right.bBox;
start = right.start;
end = right.end;
pStart = right.pStart;
pEnd = right.pEnd;
pRange = right.pRange;
bounded = right.bounded;
sameSense = right.sameSense;
}
G4BSplineCurve& G4BSplineCurve::operator=(const G4BSplineCurve& right)
{
if (&right == this) return *this;
delete [] controlPointsList;
delete [] knots;
delete [] weightsData;
Init(right.degree, right.controlPointsList,
right.knots, right.weightsData);
bBox = right.bBox;
start = right.start;
end = right.end;
pStart = right.pStart;
pEnd = right.pEnd;
pRange = right.pRange;
bounded = right.bounded;
sameSense = right.sameSense;
return *this;
}
// add by L. Broglia to pass linkage
G4double G4BSplineCurve::GetPMax() const
{
return 0.0;
}
G4Point3D G4BSplineCurve::GetPoint(G4double) const
{
return G4Point3D(0, 0, 0);
}
G4double G4BSplineCurve::GetPPoint(const G4Point3D&) const
{
return 0.0;
}
/*
#include "G4CurveRayIntersection.hh"
void G4BSplineCurve::IntersectRay2D(const G4Ray& ray,
G4CurveRayIntersection& is)
{
}
*/
G4int G4BSplineCurve::IntersectRay2D(const G4Ray&)
{
// L. Broglia
G4cout<<"\nWarning ! G4BSplineCurve::IntersectRay2D is empty.";
return 0;
}
/*
void G4BSplineCurve::CalcCurvePlaneNormal()
{
//Calc Normal for surface which is used for the projection
G4ThreeVec norm;
G4Point3d Pt1 = ControlPointList->get(0,0);
G4Point3d Pt2 = ControlPointList->get(0,1);
G4Point3d Pt3 = ControlPointList->get(0,2);
G4Point3d a(Pt2.X()-Pt1.X(), Pt2.Y()-Pt1.Y(), Pt2.Z()-Pt1.Z());
G4Point3d b(Pt3.X()-Pt1.X(), Pt3.Y()-Pt1.Y(), Pt3.Z()-Pt1.Z());
norm.X((a.Y()*b.Z() - a.Z()*b.Y()));
norm.Y((a.X()*b.Z() - a.Z()*b.X()));
norm.Z((a.X()*b.Y() - a.Y()*b.X()));
}
*/
G4Curve* G4BSplineCurve::Project(const G4Transform3D& tr)
{
// just transform + project all control points
// what about self intersections?
G4int n = controlPointsList->size();
G4Point3DVector* newControlPointsList = new G4Point3DVector(n);
for (G4int i=0; i<n; i++)
{
G4Point3D& p= (*newControlPointsList)[i];
p= tr*(*controlPointsList)[i];
p.setZ(0);
}
G4doubleVector* newKnots= new G4doubleVector(*knots);
G4doubleVector* newWeightsData=
weightsData ? new G4doubleVector(*weightsData) : 0;
G4BSplineCurve* r= new G4BSplineCurve;
r->Init(degree, newControlPointsList, newKnots, newWeightsData);
if (IsBounded())
{
r->SetBounds(GetPStart(), GetPEnd());
}
return r;
}
/*
void G4BSplineCurve::ProjectCurve(const G4Plane& Pl1, const G4Plane& Pl2)
{
int rows = ControlPointList->GetRows();
int cols = ControlPointList->GetCols();
int NumberOfPoints = cols * rows;
ProjectedControlPoints = new G4Point2d*[NumberOfPoints];
// Loop through points and do projection
for(int a = 0; a<NumberOfPoints;a++)
{
// Create 2d-point
ProjectedControlPoints[a] = new G4Point2d;
// Project 3d points into 2d
Project((*ProjectedControlPoints[a]), ControlPointList->get(0,a), Pl1, Pl2);
}
}
int G4BSplineCurve::Inside( const G4Point3d& Hit, const G4Ray& rayref)
{
const G4Plane& Pl1 = rayref.GetPlane(0);
const G4Plane& Pl2 = rayref.GetPlane(1);
register G4double DistA1, DistA2, DistB1, DistB2;
// Calc distance from Start point to ray planes
DistA1 = Start.PlaneDistance(Pl1);
// Calc distance from End point to ray planes
DistB1 = End.PlaneDistance(Pl1);
if((DistA1<0 && DistB1>0)||(DistA1>0 && DistB1 <0))
{
DistA2 = Start.PlaneDistance(Pl2);
DistB2 = End.PlaneDistance(Pl2);
// This checks the line Start-End of the convex hull
if(DistA2<0&&DistB2<0)
return 1;
}
// Test for the other lines of the convex hull
// If one of them is on a different side than the
// previously checked line, the curve has to be evaluated
// against the G4Plane.
int Points = ControlPointList->GetCols();
G4Point *CPoint1, *CPoint2;
register G4double CDistA1,CDistA2, CDistB1, CDistB2;
int Flag=0;
for(int a=0;a<Points-1;a++)
{
CPoint1 = &ControlPointList->get(0,a);
CPoint2 = &ControlPointList->get(0,a+1);
CDistA1 = CPoint1->PlaneDistance(Pl1);
CDistB1 = CPoint2->PlaneDistance(Pl1);
if((CDistA1<0 && CDistB1>0)||(CDistA1>0 && CDistB1<0))
{
CDistA2 = CPoint1->PlaneDistance(Pl2);
CDistB2 = CPoint2->PlaneDistance(Pl2);
if (!(CDistA2<0&&CDistB2<0))
{
Flag=1;
break;
}
}
}
if(!Flag)
return 1;
else
{
// Evaluate curve & Pl1 intersection, Calc the intersections distance
// from Pl2 to check which side it lies on.
G4Point3d IntPoint;
// G4cout << "\nG4B_SplineCurve.cc:Inside - Evaluation not yet implemented!!!\n";
// IntPoint = ...
G4double IntDist = IntPoint.PlaneDistance(Pl2);
if(IntDist<0)
return 1;
}
return 0;
}
*/
void G4BSplineCurve::InitBounded()
{
// just like in the old functions
G4int pointCount = controlPointsList->size();
bBox.Init( (*controlPointsList)[0] );
for (G4int i=1; i<pointCount; i++)
{
bBox.Extend( (*controlPointsList)[i] );
}
}
/*
G4Point3d G4BSplineCurve::GetBoundMin()
{
G4Point3d Min = PINFINITY;
int PointCount = ControlPointList->GetCols();
G4Point3d Tmp;
for(int a=0;a<PointCount;a++)
{
Tmp = ControlPointList->get(0,a);
Min > Tmp;
}
return Min;
}
G4Point3d G4BSplineCurve::GetBoundMax()
{
G4Point3d Max = -PINFINITY;
G4Point3d Tmp;
int PointCount = ControlPointList->GetCols();
for(int a=0;a<PointCount;a++)
{
Tmp = ControlPointList->get(0,a);
Max > Tmp;
}
return Max;
}
*/
G4bool G4BSplineCurve::Tangent(G4CurvePoint&, G4Vector3D&)
{
G4Exception("G4BSplineCurve::Tangent()", "NotImplemented",
FatalException, "Sorry, not implemented !");
return false;
}