source: sasview/src/sas/sascalc/simulation/pointsmodelpy/libpointsmodelpy/lores_model.cc @ b812771

Last change on this file since b812771 was d85c194, checked in by Piotr Rozyczko <piotr.rozyczko@…>, 9 years ago

Remaining modules refactored

  • Property mode set to 100644
File size: 5.9 KB
Line 
1/** \file lores_model.cc */
2
3#include <algorithm>
4#include <stdexcept>
5#include "lores_model.h"
6#include "sphere.h"
7#include "hollow_sphere.h"
8#include "cylinder.h"
9#include "ellipsoid.h"
10#include "single_helix.h"
11#include "Point3D.h"
12
13LORESModel::LORESModel(double density)
14{
15  density_ = density;
16}
17
18GeoShape* LORESModel::GetGeoShape(GeoShape& geo_shape)
19{
20  GeoShape* shape = NULL;
21
22  switch (geo_shape.GetShapeType()){
23    case SPHERE:
24      shape = new Sphere(static_cast<const Sphere&>(geo_shape));
25      break;
26    case HOLLOWSPHERE:
27      shape = new HollowSphere(static_cast<const HollowSphere&>(geo_shape));
28      break;
29    case CYLINDER:
30      shape = new Cylinder(static_cast<const Cylinder&>(geo_shape));
31      break;
32    case ELLIPSOID:
33      shape = new Ellipsoid(static_cast<const Ellipsoid&>(geo_shape));
34      break;
35    case SINGLEHELIX:
36      shape = new SingleHelix(static_cast<const SingleHelix&>(geo_shape));
37      break;
38 
39  }
40
41  return shape;
42}
43
44LORESModel::~LORESModel()
45{
46  for (RealSpaceShapeCollection::iterator it = shapes_.begin();
47       it != shapes_.end(); ++it) {
48    delete *it;
49  }
50}
51
52void LORESModel::SetDensity(double density)
53{
54  density_ = density;
55}
56
57double LORESModel::GetDensity()
58{
59  return density_;
60}
61
62// Add a shape into LORES Model
63void LORESModel::Add(GeoShape& geo_shape,
64                     double sld) {
65  GeoShape* shape = GetGeoShape(geo_shape);
66  assert(shape != NULL);
67
68  RealSpaceShape* real_shape = new RealSpaceShape(shape);
69  FillPoints(real_shape, sld);
70  shapes_.push_back(real_shape);
71}
72
73// Delete ith shape in shapes_ list
74// If we have 3 shapes in our model, the index starts
75// from 0, which means we need to call Delete(0) to delete
76// the first shape, and call Delete(1) to delete the second
77// shape, etc..
78void LORESModel::Delete(size_t i) {
79  if (i >= shapes_.size()) {
80    std::cerr << "Delete shapes out of scope" << std::endl;
81    return;
82  }
83
84  RealSpaceShape* real_shape = shapes_[i];
85  if (i + 1 < shapes_.size()) {
86    // if it is not the last shape, we have to distribute its points
87    // to the shapes after i-th shape.
88    const Point3DVector& points = real_shape->points;
89    for (Point3DVector::const_iterator pit = points.begin();
90         pit != points.end(); ++pit)
91      DistributePoint(*pit, i + 1);
92  }
93
94  shapes_.erase(shapes_.begin() + i);
95  delete real_shape;
96}
97
98// Get the points in the realspaceshapecollection
99int LORESModel::GetPoints(Point3DVector &pp)
100{
101  if (pp.size() != 0){
102    throw runtime_error("GetPoints(Point3DVector &VP):VP has to be empty"); 
103  }
104
105  if (shapes_.size() != 0){
106    for (size_t j = 0; j <shapes_.size(); ++j ){
107      pp.insert(pp.end(),shapes_[j]->points.begin(),shapes_[j]->points.end());
108    }
109  }
110  return pp.size();
111}
112
113//Write points to a file, mainly for testing right now
114void LORESModel::WritePoints2File(Point3DVector &vp){
115  ofstream outfile("test.coor");
116  for(size_t i=0; i<vp.size(); ++i){
117    outfile<<vp[i].getX()<<" "<<vp[i].getY()<<" "<<vp[i].getZ()<<" "<<vp[i].getSLD()<<endl;
118  }
119}
120
121double LORESModel::GetDimBound()
122{
123  if(shapes_.size() == 0)
124    return 0;
125
126  //find maximum distance between centers of shapes
127  //get the vector of centers
128  vector<Point3D> vec_center;
129  for (size_t m = 0; m < shapes_.size(); ++m){
130    assert(shapes_[m]->shape != NULL);
131    vector<double> center(3);
132    center = shapes_[m]->shape->GetCenter();
133    Point3D p_center;
134    p_center.set(center[0],center[1],center[2]);
135    vec_center.push_back(p_center);
136  }
137  size_t vecsize = vec_center.size();
138
139  //get the maximum distance among centers
140  double max_cen_dist;
141  if (vecsize == 1){
142    max_cen_dist = 0;
143  }
144  else{
145    vector<double> vecdist;
146    for (size_t m1=0; m1<vecsize -1; ++m1){
147      for (size_t m2 = m1+1; m2<vecsize; ++m2){
148        double dist = vec_center[m1].distanceToPoint(vec_center[m2]);
149        vecdist.push_back(dist);
150      }
151    }
152    max_cen_dist = *max_element(vecdist.begin(), vecdist.end());
153  }
154  //find the maximum radius for individual shape
155  vector<double> maxradii;
156  for (size_t n = 0; n < shapes_.size(); ++n){
157    assert(shapes_[n]->shape != NULL);
158    double maxradius = shapes_[n]->shape->GetMaxRadius();
159    maxradii.push_back(maxradius);
160  }
161  double max_maxradius = *max_element(maxradii.begin(),maxradii.end());
162 
163  return 2*(max_cen_dist/2 + max_maxradius);
164}
165
166
167// Distribute points of the shape we are going to delete
168void LORESModel::DistributePoint(const Point3D& point, size_t i)
169{
170  for (size_t k = i; k < shapes_.size(); ++k) {
171    assert(shapes_[k]->shape != NULL);
172    if (shapes_[k]->shape->IsInside(point)) {
173      shapes_[k]->points.push_back(point);
174      return;
175    }
176  }
177}
178
179void LORESModel::FillPoints(RealSpaceShape* real_shape, double sld)
180{
181  assert(real_shape != NULL);
182
183  GeoShape* shape = real_shape->shape;
184  assert(shape != NULL);
185
186  int npoints = static_cast<int>(density_ * shape->GetVolume());
187
188  for (int i = 0; i < npoints; ++i){
189    Point3D apoint = shape->GetAPoint(sld);
190    apoint.Transform(shape->GetOrientation(),shape->GetCenter());
191    if (!IsInside(apoint)){
192      real_shape->points.push_back(apoint);
193    }
194  }
195
196}
197
198bool LORESModel::IsInside(const Point3D& point)
199{
200  for (RealSpaceShapeCollection::const_iterator it = shapes_.begin();
201       it != shapes_.end(); ++it) {
202    const GeoShape* shape = (*it)->shape;
203    assert(shape != NULL);
204
205    if (shape->IsInside(point)) {
206       return true;
207    }
208  }
209
210  return false;
211}
212
213vector<double> LORESModel::GetCenter()
214{
215  //get the vector of centers from the list of shapes
216  size_t numshapes = 0;
217  double sumx = 0, sumy = 0, sumz = 0;
218  for (size_t m = 0; m < shapes_.size(); ++m){
219    assert(shapes_[m]->shape != NULL);
220    vector<double> center(3);
221    center = shapes_[m]->shape->GetCenter();
222
223    sumx += center[0];
224    sumy += center[1];
225    sumz += center[2];
226
227    ++numshapes;
228  }
229
230  vector<double> shapescenter(3);
231  shapescenter[0]= sumx/numshapes;
232  shapescenter[1]= sumy/numshapes;
233  shapescenter[2]= sumz/numshapes;
234
235  center_ = shapescenter;
236  return center_;
237}
Note: See TracBrowser for help on using the repository browser.