-
Notifications
You must be signed in to change notification settings - Fork 0
/
VisualObject.h
155 lines (119 loc) · 3.84 KB
/
VisualObject.h
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
// ****************************
// A class for visual objects
//
// Matthew Setzler 4/19/17
// ****************************
#include <cmath>
#include <iostream>
// A visual ray – line segment of form y = mx + b with start coordinates and length
typedef struct {
double b;
double m;
double startX;
double startY;
double length;
} Ray;
// The VisualObject class declaration
class VisualObject {
public:
// The constructor
VisualObject(double ix = 0.0, double iy = 275.0, double vy_ = -3.0, double size_ = 30.0) {
cx = ix; cy = iy;
vy = vy_;
size = size_;
};
// The deconstructor
~VisualObject() {};
// Updates ray length if an intersection occurs
// Assumes agent is 'looking up' at object
virtual void RayIntersection(Ray &ray) {};
// Accessors
void SetPositionX(double x) {cx = x;};
void SetPositionY(double y) {cy = y;};
double PositionX() {return cx;};
double PositionY() {return cy;};
void Step(double StepSize) {
cy += StepSize * vy;
};
void Print(){
cout <<"VisualObject = " << this->WhoAmI() << ", cx = " << cx << ", cy= " << cy << ", vy = " << vy << ", size= " << size << endl;
}
string virtual WhoAmI(){
return "VisualObject";
}
protected:
double cx,cy,vy,size;
};
// Class for horizontal line segment
class Line : public VisualObject {
public:
// The constructor
// size --> length of segment
Line(double ix = 0.0, double iy = 275.0, double vy_ = -3.0, double size_ = 30.0)
: VisualObject(ix,iy,vy_,size_) {};
// The deconstructor
~Line() {};
void RayIntersection(Ray &ray) {
double x_intersect;
if (ray.m == INFINITY) {
x_intersect = ray.startX;
} else {
x_intersect = (cy - ray.b)/ray.m;
}
// No intersection
if ((fabs(cx-x_intersect) > size/2.0) || (cy < 0)) return;
// Intersection, return distance
double new_length = sqrt(pow(x_intersect-ray.startX, 2.0) + pow(cy-ray.startY, 2.0));
if (new_length < ray.length) ray.length = new_length;
};
string WhoAmI(){
return "Line";
}
};
// Class definition for a circle
class Circle : public VisualObject {
public:
// The constructor
// size --> diameter
Circle(double ix = 0.0, double iy = 275.0, double vy_ = -3.0, double size_ = 30.0)
: VisualObject(ix,iy,vy_,size_) {};
// The deconstructor
~Circle() {};
void RayIntersection(Ray &ray) {
// Special case, vertical ray
if (ray.m == INFINITY) {
if (fabs(ray.startX-cx) > size/2) return;
double x_intersect = ray.startX;
double A = 1;
double B = -2*cy;
double C = pow(cy,2)-pow(size/2,2)+pow(x_intersect-cx,2);
double disc = pow(B,2)-4*A*C;
double y_intersect = (-B-sqrt(disc))/(2*A); // assuming cy>0 and cy>ray.startY
double new_length = fabs(y_intersect-ray.startY);
if (new_length < ray.length) ray.length = new_length;
return;
}
double A = 1 + pow(ray.m, 2);
double B = 2*(ray.m*(ray.b-cy)-cx);
double C = pow(cx,2)+pow(ray.b,2)-2*ray.b*cy+pow(cy,2)-pow(size/2,2);
double disc = pow(B,2)-4*A*C;
if (disc < 0) return; // No intersection
// Find points of intersection, return smaller distance (distances are the same for tangent lines)
double x_intersect1 = (-B+sqrt(disc))/(2*A);
double y_intersect1 = ray.m*x_intersect1 + ray.b;
double distance1 = sqrt(pow(x_intersect1-ray.startX,2)+pow(y_intersect1-ray.startY,2));
double x_intersect2 = (-B-sqrt(disc))/(2*A);
double y_intersect2 = ray.m*x_intersect2 + ray.b;
double distance2 = sqrt(pow(x_intersect2-ray.startX,2)+pow(y_intersect2-ray.startY,2));
double new_length;
if (distance1 < distance2) {
new_length = distance1;
} else {
new_length = distance2;
}
if (new_length < ray.length) ray.length = new_length;
};
string WhoAmI(){
return "Circle";
}
};