forked from precious/dr_program
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtypes.cpp
More file actions
162 lines (139 loc) · 6.12 KB
/
types.cpp
File metadata and controls
162 lines (139 loc) · 6.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
#include "types.h"
#include <assert.h>
Point POINT_OF_ORIGIN = Point(0,0,0);
Point Point::operator+(Vector v) {
return Point(x + v.x,y + v.y, z + v.z);
}
Point Point::operator-(Vector v) {
return Point(x - v.x,y - v.y, z - v.z);
}
Particle Particle::operator+(Vector v) {
return Particle(Point(*this) + v,step,ttl,type,polygonIndex);
}
Particle Particle::operator-(Vector v) {
return Particle(Point(*this) - v,step,ttl,type,polygonIndex);
}
Plane::Plane(Point p, Vector v):
ThreePoints(p,p + Geometry::getRandomOrthogonalVector(v),
p + Geometry::getRandomOrthogonalVector(v)) {}
void GenerativeSphere::checkForIntersectionsAndSetTtl(Particle &p) {
p.polygonIndex = Geometry::getIndexOfPolygonThatParicleIntersects(object,p);
if (p.polygonIndex != -1) {
p.ttl = Geometry::getDistanceBetweenPoints(p,
Geometry::getPlaneAndLineIntersection2(object.polygons->at(p.polygonIndex),Line(p,p.step)))/p.step.length();
} else { // see description at page 11 of the draft
p.ttl = 2*radius*p.step.cos(Vector(p,center)) / p.step.length();
}
}
Particle GenerativeSphere::generateParticleInSphere(int type) {
Point initialPosition = Geometry::getRandomPointFromSphere2(*this);
Vector step(Time::getRandom() - 0.5,Time::getRandom() - 0.5,Time::getRandom() - 0.5);
switch(type) {
case PTYPE_ELECTRON:
step = step.resized(electronVelocityGenerator()) - objectStep;
break;
case PTYPE_ION:
step = step.resized(ionVelocityGenerator()) - objectStep;
break;
}
Particle p(initialPosition,step,0,type);
checkForIntersectionsAndSetTtl(p);
return p;
}
Particle GenerativeSphere::generateParticleWhichIntersectsObject(int type,bool isParticleOnSphere) {
int polygonIndex = RAND(object.polygons->size());
Vector n = object.polygons->at(polygonIndex).getNormal().normalized();
velocity particleSpeed;
switch(type) {
case PTYPE_ELECTRON:
particleSpeed = electronVelocityGenerator();
break;
case PTYPE_ION:
particleSpeed = ionVelocityGenerator();
break;
}
Point p = Geometry::getRandomPointFromTriangle(object.polygons->at(polygonIndex));
Line auxLine(p,(object.polygons->at(polygonIndex).a != p)?
object.polygons->at(polygonIndex).a: object.polygons->at(polygonIndex).b);
// see explanation at page 2 of draft
if (particleSpeed <= -object.speed*n.cos(objectStep)) {
particleSpeed = Time::getRandom(max<velocity>(0.1,-object.speed*n.cos(objectStep)),2.*ELECTRON_VELOCITY_M); /// TODO fix me
}
double cos = Time::getRandom(-1,min<velocity>(1,object.speed*n.cos(objectStep)/particleSpeed));
// see explanation at page 8 of draft
Vector s(p,Geometry::rotatePointAroundLine(p + n,auxLine,acos(cos)));
s = s.resized(particleSpeed) - objectStep;
real distanceBetweenParticleAndPolygon;
if (isParticleOnSphere) {
// now we should calculate point on sphere were particle will be initially placed
// see explanation at page 1 of draft
real a = Geometry::getDistanceBetweenPoints(center,p);
cos = Vector(center,p).cos(s);
distanceBetweenParticleAndPolygon = sqrt(a*a*(cos*cos - 1) + radius*radius) + a*cos;
// now p is point on sphere
p = p - s.resized(distanceBetweenParticleAndPolygon);
//assert (abs(radius - GU::getDistanceBetweenPoints(p,center)) <= 0.00001);
} else {
// see explanation at page 5 of draft
real distanceBetweenParticleAndPolygon = sqrt(Time::getRandom(object.radius,radius)*radius);
p = p - s.resized(distanceBetweenParticleAndPolygon);
}
return Particle(p,s,distanceBetweenParticleAndPolygon/particleSpeed,type,polygonIndex);
}
Particle GenerativeSphere::generateParticleOnSphere(int type) {
Point initialPosition = Geometry::getRandomPointOnSphere(*this);
Vector step(initialPosition,Geometry::getRandomPointOnSphere(*this));
switch(type) {
case PTYPE_ELECTRON:
step = step.resized(electronVelocityGenerator()) - objectStep;
break;
case PTYPE_ION:
step = step.resized(ionVelocityGenerator()) - objectStep;
break;
}
Particle p(initialPosition,step,0,type);
checkForIntersectionsAndSetTtl(p);
return p;
}
void GenerativeSphere::populateArray(Particle *particles,int number,int type,int FLAGS) {
int n = 0;
bool isOnSphere = FLAGS & GEN_ON_SPHERE;
if (FLAGS & GEN_INTERSECT_OBJ)
for(;n < number;++n) {
particles[n] = generateParticleWhichIntersectsObject(type,isOnSphere);
}
else if (FLAGS & GEN_RANDOM)
for(;n < number;++n) {
particles[n] = generateParticleInSphere(type);
}
else if (isOnSphere)
for(;n < number;++n) {
particles[n] = generateParticleOnSphere(type);
}
}
void Object3D::init() {
charge = 0;
speed = ORBITAL_VELOCITY;
nearestPoint = furthermostPoint = maxCoords = minCoords = polygons->at(0).set[0];
for(vector<PlaneType>::iterator it = polygons->begin();it != polygons->end();it++)
for(int i = 0;i < 3;i++) {
if (Vector(nearestPoint,(*it).set[i]).cos(front) > 0)
nearestPoint = (*it).set[i];
if (Vector(furthermostPoint,(*it).set[i]).cos(front) < 0)
furthermostPoint = (*it).set[i];
if (maxCoords.x < (*it).set[i].x) maxCoords.x = (*it).set[i].x;
if (maxCoords.y < (*it).set[i].y) maxCoords.y = (*it).set[i].y;
if (maxCoords.z < (*it).set[i].z) maxCoords.z = (*it).set[i].z;
if (minCoords.x > (*it).set[i].x) minCoords.x = (*it).set[i].x;
if (minCoords.y > (*it).set[i].y) minCoords.y = (*it).set[i].y;
if (minCoords.z > (*it).set[i].z) minCoords.z = (*it).set[i].z;
}
center = Point((maxCoords.x + minCoords.x)/2,
(maxCoords.y + minCoords.y)/2,
(maxCoords.z + minCoords.z)/2);
radius = Geometry::getDistanceBetweenPoints(center,maxCoords);
polygonsCharges = new double[polygons->size()];
for(unsigned int i = 0;i < polygons->size();++i) {
polygonsCharges[i] = 0;
}
}