forked from vectozavr/pseudo3DEngine
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Circle2D.cpp
64 lines (57 loc) · 1.98 KB
/
Circle2D.cpp
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
//
// Created by ivan- on 21.01.2020.
//
#include "Circle2D.h"
#include "settings.h"
Circle2D::Circle2D(double radius, Point2D position, double height, const std::string& texture, int convexNumber)
: Object2D(position, {}, height, texture), d_radius(radius)
{
for (int i = 0; i < convexNumber; i++)
{
double _x = d_radius * cos((double)i / convexNumber * 2 * PI + PI / 4);
double _y = d_radius * sin((double)i / convexNumber * 2 * PI + PI / 4);
nodes().push_back({ _x, _y });
}
}
ObjectType Circle2D::type()
{
return ObjectType::Circle;
}
bool Circle2D::cross(const std::pair<Point2D, Point2D>& ray, std::pair<Point2D, Point2D>& wall, Point2D& point, double& uv)
{
bool success = false;
Point2D d = ray.second - ray.first;
Point2D f = ray.first - p_position;
float a = static_cast<float>(d.x * d.x + d.y * d.y);
float b = static_cast<float>(2 * (f.x * d.x + f.y * d.y));
float c = static_cast<float>((f.x * f.x + f.y * f.y) - d_radius * d_radius);
float discriminant = b * b - 4 * a * c;
if (discriminant >= 0)
{
discriminant = sqrt(discriminant);
float t1 = (-b - discriminant) / (2 * a);
float t2 = (-b + discriminant) / (2 * a);
if (t1 >= 0 && t1 <= 1)
{
point.x = ray.first.x + t1 * d.x;
point.y = ray.first.y + t1 * d.y;
success = true;
}
else if (t2 >= 0 && t2 <= 1)
{
point.x = ray.first.x + t2 * d.x;
point.y = ray.first.y + t2 * d.y;
success = true;
}
}
if (success)
{
double cx = cos(PI / 4), cy = sin(PI / 4);
Point2D diff = point - p_position;
double angle = atan2((cx * diff.y - cy * diff.x) / d_radius, (cx * diff.x + cy * diff.y) / d_radius);
wall.first = { p_position.x + diff.y, p_position.y - diff.x };
wall.second = { p_position.x - diff.y, p_position.y + diff.x };
uv = d_radius * angle;
}
return success;
}