// @(#):\$Id\$
// Author: Mihaela Gheata   03/08/04

/*************************************************************************
*                                                                       *
* For the licensing terms see \$ROOTSYS/LICENSE.                         *
* For the list of contributors see \$ROOTSYS/README/CREDITS.             *
*************************************************************************/

//_____________________________________________________________________________
// TGeoHalfSpace - A half-space defined by:
//            p[3] - an arbitrary point on the plane
//            n[3] - normal at the plane in point P
//    A half-space is not really a shape, because it is infinite. The normal
//    points "outside" the half-space
//_____________________________________________________________________________

#include "Riostream.h"
#include "TGeoHalfSpace.h"
#include "TMath.h"

ClassImp(TGeoHalfSpace)

//_____________________________________________________________________________
TGeoHalfSpace::TGeoHalfSpace()
{
// Dummy constructor
SetShapeBit(TGeoShape::kGeoHalfSpace);
SetShapeBit(TGeoShape::kGeoInvalidShape);
memset(fP, 0, 3*sizeof(Double_t));
memset(fN, 0, 3*sizeof(Double_t));
}

//_____________________________________________________________________________
TGeoHalfSpace::TGeoHalfSpace(const char *name, Double_t *p, Double_t *n)
:TGeoBBox(name, 0,0,0)
{
// Constructor with name, point on the plane and normal
SetShapeBit(TGeoShape::kGeoHalfSpace);
SetShapeBit(TGeoShape::kGeoInvalidShape);
Double_t param[6];
memcpy(param, p, 3*sizeof(Double_t));
memcpy(&param[3], n, 3*sizeof(Double_t));
SetDimensions(param);
}

//_____________________________________________________________________________
TGeoHalfSpace::TGeoHalfSpace(Double_t *param)
:TGeoBBox(0,0,0)
{
// Default constructor specifying minimum and maximum radius
SetShapeBit(TGeoShape::kGeoHalfSpace);
SetShapeBit(TGeoShape::kGeoInvalidShape);
SetDimensions(param);
}

//_____________________________________________________________________________
TGeoHalfSpace::~TGeoHalfSpace()
{
// destructor
}

//_____________________________________________________________________________
void TGeoHalfSpace::ComputeNormal(const Double_t * /*point*/, const Double_t *dir, Double_t *norm)
{
// Compute normal to closest surface from POINT.
memcpy(norm, fN, 3*sizeof(Double_t));
if (norm[0]*dir[0]+norm[1]*dir[1]+norm[2]*dir[2]<0) {
norm[0] = -norm[0];
norm[1] = -norm[1];
norm[2] = -norm[2];
}
}

//_____________________________________________________________________________
Bool_t TGeoHalfSpace::Contains(const Double_t *point) const
{
// test if point is inside the half-space
Double_t r[3];
r[0] = fP[0]-point[0];
r[1] = fP[1]-point[1];
r[2] = fP[2]-point[2];
Double_t rdotn = r[0]*fN[0]+r[1]*fN[1]+r[2]*fN[2];
if (rdotn < 0) return kFALSE;
return kTRUE;
}

//_____________________________________________________________________________
Int_t TGeoHalfSpace::DistancetoPrimitive(Int_t /*px*/, Int_t /*py*/)
{
// A half-space does not have a mesh primitive
return 999;
}

//_____________________________________________________________________________
Double_t TGeoHalfSpace::DistFromInside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
{
// compute distance from inside point to the plane
Double_t r[3];
r[0] = fP[0]-point[0];
r[1] = fP[1]-point[1];
r[2] = fP[2]-point[2];
Double_t rdotn = r[0]*fN[0]+r[1]*fN[1]+r[2]*fN[2];
if (iact<3 && safe) {
*safe = rdotn;
if (iact==0) return TGeoShape::Big();
if ((iact==1) && (*safe>step)) return TGeoShape::Big();
}
// compute distance to plane
Double_t snxt = TGeoShape::Big();
Double_t ddotn = dir[0]*fN[0]+dir[1]*fN[1]+dir[2]*fN[2];
if (TMath::Abs(ddotn)<TGeoShape::Tolerance()) return snxt;
snxt = rdotn/ddotn;
if (snxt<0) return TGeoShape::Big();
return snxt;
}

//_____________________________________________________________________________
Double_t TGeoHalfSpace::DistFromOutside(const Double_t *point, const Double_t *dir, Int_t iact, Double_t step, Double_t *safe) const
{
// compute distance from inside point to the plane
Double_t r[3];
r[0] = fP[0]-point[0];
r[1] = fP[1]-point[1];
r[2] = fP[2]-point[2];
Double_t rdotn = r[0]*fN[0]+r[1]*fN[1]+r[2]*fN[2];
if (iact<3 && safe) {
*safe = -rdotn;
if (iact==0) return TGeoShape::Big();
if ((iact==1) && (step<*safe)) return TGeoShape::Big();
}
// compute distance to plane
Double_t snxt = TGeoShape::Big();
Double_t ddotn = dir[0]*fN[0]+dir[1]*fN[1]+dir[2]*fN[2];
if (TMath::Abs(ddotn)<TGeoShape::Tolerance()) return snxt;
snxt = rdotn/ddotn;
if (snxt<0) return TGeoShape::Big();
return snxt;
}

//_____________________________________________________________________________
TGeoVolume *TGeoHalfSpace::Divide(TGeoVolume * /*voldiv*/, const char * /*divname*/, Int_t /*iaxis*/, Int_t /*ndiv*/,
Double_t /*start*/, Double_t /*step*/)
{
// Divide the shape along one axis.
Error("Divide", "Half-spaces cannot be divided");
return 0;
}

//_____________________________________________________________________________
void TGeoHalfSpace::GetMeshNumbers(Int_t &nvert, Int_t &nsegs, Int_t &npols) const
{
// Returns numbers of vertices, segments and polygons composing the shape mesh.
nvert = 0;
nsegs = 0;
npols = 0;
}

//_____________________________________________________________________________
void TGeoHalfSpace::InspectShape() const
{
// print shape parameters
printf("*** Shape %s: TGeoHalfSpace ***\n", GetName());
printf("    Point    : %11.5f, %11.5f, %11.5f\n", fP[0], fP[1], fP[2]);
printf("    Normal   : %11.5f, %11.5f, %11.5f\n", fN[0], fN[1], fN[2]);
}

//_____________________________________________________________________________
Double_t TGeoHalfSpace::Safety(const Double_t *point, Bool_t /*in*/) const
{
// computes the closest distance from given point to this shape, according
// to option. The matching point on the shape is stored in spoint.
Double_t r[3];
r[0] = fP[0]-point[0];
r[1] = fP[1]-point[1];
r[2] = fP[2]-point[2];
Double_t rdotn = r[0]*fN[0]+r[1]*fN[1]+r[2]*fN[2];
return TMath::Abs(rdotn);
}

//_____________________________________________________________________________
void TGeoHalfSpace::SavePrimitive(std::ostream &out, Option_t * /*option*/ /*= ""*/)
{
// Save a primitive as a C++ statement(s) on output stream "out".
if (TObject::TestBit(kGeoSavePrimitive)) return;
out << "   // Shape: " << GetName() << " type: " << ClassName() << std::endl;
out << "   point[0] = " << fP[0] << ";" << std::endl;
out << "   point[1] = " << fP[1] << ";" << std::endl;
out << "   point[2] = " << fP[2] << ";" << std::endl;
out << "   norm[0]  = " << fN[0] << ";" << std::endl;
out << "   norm[1]  = " << fN[1] << ";" << std::endl;
out << "   norm[2]  = " << fN[2] << ";" << std::endl;
out << "   TGeoShape *" << GetPointerName() << " = new TGeoHalfSpace(\"" << GetName() << "\", point,norm);" << std::endl;
TObject::SetBit(TGeoShape::kGeoSavePrimitive);
}

//_____________________________________________________________________________
void TGeoHalfSpace::SetDimensions(Double_t *param)
{
// Set half-space parameters as stored in an array.
memcpy(fP, param, 3*sizeof(Double_t));
memcpy(fN, &param[3], 3*sizeof(Double_t));
Double_t nsq = TMath::Sqrt(fN[0]*fN[0]+fN[1]*fN[1]+fN[2]*fN[2]);
fN[0] /= nsq;
fN[1] /= nsq;
fN[2] /= nsq;
}

//_____________________________________________________________________________
void TGeoHalfSpace::Contains_v(const Double_t *points, Bool_t *inside, Int_t vecsize) const
{
// Check the inside status for each of the points in the array.
// Input: Array of point coordinates + vector size
// Output: Array of Booleans for the inside of each point
for (Int_t i=0; i<vecsize; i++) inside[i] = Contains(&points[3*i]);
}

//_____________________________________________________________________________
void TGeoHalfSpace::ComputeNormal_v(const Double_t *points, const Double_t *dirs, Double_t *norms, Int_t vecsize)
{
// Compute the normal for an array o points so that norm.dot.dir is positive
// Input: Arrays of point coordinates and directions + vector size
// Output: Array of normal directions
for (Int_t i=0; i<vecsize; i++) ComputeNormal(&points[3*i], &dirs[3*i], &norms[3*i]);
}

//_____________________________________________________________________________
void TGeoHalfSpace::DistFromInside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
{
// Compute distance from array of input points having directions specisied by dirs. Store output in dists
for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromInside(&points[3*i], &dirs[3*i], 3, step[i]);
}

//_____________________________________________________________________________
void TGeoHalfSpace::DistFromOutside_v(const Double_t *points, const Double_t *dirs, Double_t *dists, Int_t vecsize, Double_t* step) const
{
// Compute distance from array of input points having directions specisied by dirs. Store output in dists
for (Int_t i=0; i<vecsize; i++) dists[i] = DistFromOutside(&points[3*i], &dirs[3*i], 3, step[i]);
}

//_____________________________________________________________________________
void TGeoHalfSpace::Safety_v(const Double_t *points, const Bool_t *inside, Double_t *safe, Int_t vecsize) const
{
// Compute safe distance from each of the points in the input array.
// Input: Array of point coordinates, array of statuses for these points, size of the arrays
// Output: Safety values
for (Int_t i=0; i<vecsize; i++) safe[i] = Safety(&points[3*i], inside[i]);
}
TGeoHalfSpace.cxx:1
TGeoHalfSpace.cxx:2
TGeoHalfSpace.cxx:3
TGeoHalfSpace.cxx:4
TGeoHalfSpace.cxx:5
TGeoHalfSpace.cxx:6
TGeoHalfSpace.cxx:7
TGeoHalfSpace.cxx:8
TGeoHalfSpace.cxx:9
TGeoHalfSpace.cxx:10
TGeoHalfSpace.cxx:11
TGeoHalfSpace.cxx:12
TGeoHalfSpace.cxx:13
TGeoHalfSpace.cxx:14
TGeoHalfSpace.cxx:15
TGeoHalfSpace.cxx:16
TGeoHalfSpace.cxx:17
TGeoHalfSpace.cxx:18
TGeoHalfSpace.cxx:19
TGeoHalfSpace.cxx:20
TGeoHalfSpace.cxx:21
TGeoHalfSpace.cxx:22
TGeoHalfSpace.cxx:23
TGeoHalfSpace.cxx:24
TGeoHalfSpace.cxx:25
TGeoHalfSpace.cxx:26
TGeoHalfSpace.cxx:27
TGeoHalfSpace.cxx:28
TGeoHalfSpace.cxx:29
TGeoHalfSpace.cxx:30
TGeoHalfSpace.cxx:31
TGeoHalfSpace.cxx:32
TGeoHalfSpace.cxx:33
TGeoHalfSpace.cxx:34
TGeoHalfSpace.cxx:35
TGeoHalfSpace.cxx:36
TGeoHalfSpace.cxx:37
TGeoHalfSpace.cxx:38
TGeoHalfSpace.cxx:39
TGeoHalfSpace.cxx:40
TGeoHalfSpace.cxx:41
TGeoHalfSpace.cxx:42
TGeoHalfSpace.cxx:43
TGeoHalfSpace.cxx:44
TGeoHalfSpace.cxx:45
TGeoHalfSpace.cxx:46
TGeoHalfSpace.cxx:47
TGeoHalfSpace.cxx:48
TGeoHalfSpace.cxx:49
TGeoHalfSpace.cxx:50
TGeoHalfSpace.cxx:51
TGeoHalfSpace.cxx:52
TGeoHalfSpace.cxx:53
TGeoHalfSpace.cxx:54
TGeoHalfSpace.cxx:55
TGeoHalfSpace.cxx:56
TGeoHalfSpace.cxx:57
TGeoHalfSpace.cxx:58
TGeoHalfSpace.cxx:59
TGeoHalfSpace.cxx:60
TGeoHalfSpace.cxx:61
TGeoHalfSpace.cxx:62
TGeoHalfSpace.cxx:63
TGeoHalfSpace.cxx:64
TGeoHalfSpace.cxx:65
TGeoHalfSpace.cxx:66
TGeoHalfSpace.cxx:67
TGeoHalfSpace.cxx:68
TGeoHalfSpace.cxx:69
TGeoHalfSpace.cxx:70
TGeoHalfSpace.cxx:71
TGeoHalfSpace.cxx:72
TGeoHalfSpace.cxx:73
TGeoHalfSpace.cxx:74
TGeoHalfSpace.cxx:75
TGeoHalfSpace.cxx:76
TGeoHalfSpace.cxx:77
TGeoHalfSpace.cxx:78
TGeoHalfSpace.cxx:79
TGeoHalfSpace.cxx:80
TGeoHalfSpace.cxx:81
TGeoHalfSpace.cxx:82
TGeoHalfSpace.cxx:83
TGeoHalfSpace.cxx:84
TGeoHalfSpace.cxx:85
TGeoHalfSpace.cxx:86
TGeoHalfSpace.cxx:87
TGeoHalfSpace.cxx:88
TGeoHalfSpace.cxx:89
TGeoHalfSpace.cxx:90
TGeoHalfSpace.cxx:91
TGeoHalfSpace.cxx:92
TGeoHalfSpace.cxx:93
TGeoHalfSpace.cxx:94
TGeoHalfSpace.cxx:95
TGeoHalfSpace.cxx:96
TGeoHalfSpace.cxx:97
TGeoHalfSpace.cxx:98
TGeoHalfSpace.cxx:99
TGeoHalfSpace.cxx:100
TGeoHalfSpace.cxx:101
TGeoHalfSpace.cxx:102
TGeoHalfSpace.cxx:103
TGeoHalfSpace.cxx:104
TGeoHalfSpace.cxx:105
TGeoHalfSpace.cxx:106
TGeoHalfSpace.cxx:107
TGeoHalfSpace.cxx:108
TGeoHalfSpace.cxx:109
TGeoHalfSpace.cxx:110
TGeoHalfSpace.cxx:111
TGeoHalfSpace.cxx:112
TGeoHalfSpace.cxx:113
TGeoHalfSpace.cxx:114
TGeoHalfSpace.cxx:115
TGeoHalfSpace.cxx:116
TGeoHalfSpace.cxx:117
TGeoHalfSpace.cxx:118
TGeoHalfSpace.cxx:119
TGeoHalfSpace.cxx:120
TGeoHalfSpace.cxx:121
TGeoHalfSpace.cxx:122
TGeoHalfSpace.cxx:123
TGeoHalfSpace.cxx:124
TGeoHalfSpace.cxx:125
TGeoHalfSpace.cxx:126
TGeoHalfSpace.cxx:127
TGeoHalfSpace.cxx:128
TGeoHalfSpace.cxx:129
TGeoHalfSpace.cxx:130
TGeoHalfSpace.cxx:131
TGeoHalfSpace.cxx:132
TGeoHalfSpace.cxx:133
TGeoHalfSpace.cxx:134
TGeoHalfSpace.cxx:135
TGeoHalfSpace.cxx:136
TGeoHalfSpace.cxx:137
TGeoHalfSpace.cxx:138
TGeoHalfSpace.cxx:139
TGeoHalfSpace.cxx:140
TGeoHalfSpace.cxx:141
TGeoHalfSpace.cxx:142
TGeoHalfSpace.cxx:143
TGeoHalfSpace.cxx:144
TGeoHalfSpace.cxx:145
TGeoHalfSpace.cxx:146
TGeoHalfSpace.cxx:147
TGeoHalfSpace.cxx:148
TGeoHalfSpace.cxx:149
TGeoHalfSpace.cxx:150
TGeoHalfSpace.cxx:151
TGeoHalfSpace.cxx:152
TGeoHalfSpace.cxx:153
TGeoHalfSpace.cxx:154
TGeoHalfSpace.cxx:155
TGeoHalfSpace.cxx:156
TGeoHalfSpace.cxx:157
TGeoHalfSpace.cxx:158
TGeoHalfSpace.cxx:159
TGeoHalfSpace.cxx:160
TGeoHalfSpace.cxx:161
TGeoHalfSpace.cxx:162
TGeoHalfSpace.cxx:163
TGeoHalfSpace.cxx:164
TGeoHalfSpace.cxx:165
TGeoHalfSpace.cxx:166
TGeoHalfSpace.cxx:167
TGeoHalfSpace.cxx:168
TGeoHalfSpace.cxx:169
TGeoHalfSpace.cxx:170
TGeoHalfSpace.cxx:171
TGeoHalfSpace.cxx:172
TGeoHalfSpace.cxx:173
TGeoHalfSpace.cxx:174
TGeoHalfSpace.cxx:175
TGeoHalfSpace.cxx:176
TGeoHalfSpace.cxx:177
TGeoHalfSpace.cxx:178
TGeoHalfSpace.cxx:179
TGeoHalfSpace.cxx:180
TGeoHalfSpace.cxx:181
TGeoHalfSpace.cxx:182
TGeoHalfSpace.cxx:183
TGeoHalfSpace.cxx:184
TGeoHalfSpace.cxx:185
TGeoHalfSpace.cxx:186
TGeoHalfSpace.cxx:187
TGeoHalfSpace.cxx:188
TGeoHalfSpace.cxx:189
TGeoHalfSpace.cxx:190
TGeoHalfSpace.cxx:191
TGeoHalfSpace.cxx:192
TGeoHalfSpace.cxx:193
TGeoHalfSpace.cxx:194
TGeoHalfSpace.cxx:195
TGeoHalfSpace.cxx:196
TGeoHalfSpace.cxx:197
TGeoHalfSpace.cxx:198
TGeoHalfSpace.cxx:199
TGeoHalfSpace.cxx:200
TGeoHalfSpace.cxx:201
TGeoHalfSpace.cxx:202
TGeoHalfSpace.cxx:203
TGeoHalfSpace.cxx:204
TGeoHalfSpace.cxx:205
TGeoHalfSpace.cxx:206
TGeoHalfSpace.cxx:207
TGeoHalfSpace.cxx:208
TGeoHalfSpace.cxx:209
TGeoHalfSpace.cxx:210
TGeoHalfSpace.cxx:211
TGeoHalfSpace.cxx:212
TGeoHalfSpace.cxx:213
TGeoHalfSpace.cxx:214
TGeoHalfSpace.cxx:215
TGeoHalfSpace.cxx:216
TGeoHalfSpace.cxx:217
TGeoHalfSpace.cxx:218
TGeoHalfSpace.cxx:219
TGeoHalfSpace.cxx:220
TGeoHalfSpace.cxx:221
TGeoHalfSpace.cxx:222
TGeoHalfSpace.cxx:223
TGeoHalfSpace.cxx:224
TGeoHalfSpace.cxx:225
TGeoHalfSpace.cxx:226
TGeoHalfSpace.cxx:227
TGeoHalfSpace.cxx:228
TGeoHalfSpace.cxx:229
TGeoHalfSpace.cxx:230
TGeoHalfSpace.cxx:231
TGeoHalfSpace.cxx:232
TGeoHalfSpace.cxx:233
TGeoHalfSpace.cxx:234
TGeoHalfSpace.cxx:235
TGeoHalfSpace.cxx:236
TGeoHalfSpace.cxx:237
TGeoHalfSpace.cxx:238
TGeoHalfSpace.cxx:239
TGeoHalfSpace.cxx:240
TGeoHalfSpace.cxx:241
TGeoHalfSpace.cxx:242
TGeoHalfSpace.cxx:243
TGeoHalfSpace.cxx:244
TGeoHalfSpace.cxx:245
TGeoHalfSpace.cxx:246
TGeoHalfSpace.cxx:247
TGeoHalfSpace.cxx:248
TGeoHalfSpace.cxx:249
TGeoHalfSpace.cxx:250