Gorgon Game Engine
Circle.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "../Types.h"
4 #include "../Graphics/Bitmap.h"
5 #include "../Graphics/Color.h"
6 #include "../Containers/Image.h"
7 #include "../CGI.h"
8 
9 #include <cmath>
10 
11 
12 namespace Gorgon { namespace CGI {
13 
18  template<int S_ = 8, class P_= Geometry::Pointf, class F_ = SolidFill<>>
19  void Circle(Containers::Image &target, P_ location, Float radius, F_ fill = SolidFill<>(Graphics::Color::Black)) {
20 
21  int minx = std::max((int)floor(float(location.X) - radius), 0);
22  int maxx = std::min((int)ceil(float(location.X) + radius), target.GetWidth());
23 
24  int miny = std::max((int)floor(float(location.Y) - radius), 0);
25  int maxy = std::min((int)ceil(float(location.Y) + radius), target.GetHeight());
26 
27  Float r2 = radius * radius;
28 
29  if(S_ == 1) {
30  float cury = float(miny+0.5) - location.Y;
31  for(int y=miny; y<maxy; y++, cury++) {
32  float curx = float(minx+0.5) - location.X;
33  for(int x=minx; x<maxx; x++, curx++) {
34  if(cury*cury + curx*curx < r2) {
35  auto cur = target.GetRGBAAt(x, y);
36 
37  target.SetRGBAAt(x, y, fill({curx, cury}, {x, y}, cur, 1.f));
38  }
39  }
40  }
41  }
42  else {
43  Float s2 = sqrt(2.0f);
44  Float ri2 = (radius-s2/2) * (radius-s2/2);
45  Float ro = (radius+s2/2);
46  Float ro2 = ro * ro;
47 
48  Float cury = Float(miny-0.5) - location.Y;
49  for(int y=miny-1; y<maxy+1; y++, cury++) {
50  Float curx = Float(minx-0.5) - location.X;
51  for(int x=minx-1; x<maxx+1; x++, curx++) {
52  Float d = cury*cury + curx*curx;
53 
54  if(d < ri2) {
55  auto cur = target.GetRGBAAt(x, y);
56 
57  target.SetRGBAAt(x, y, fill({curx, cury}, {x, y}, cur, 1.f));
58  }
59  else if(d < ro2) {
60  auto cur = target.GetRGBAAt(x, y);
61  Float a = (ro-sqrt(d))/s2;
62  if(a > 1)
63  a = 1;
64 
65  target.SetRGBAAt(x, y, fill({curx, cury}, {x, y}, cur, a));
66  }
67  }
68  }
69  }
70  }
71 
72  template<int S_ = 8, class P_ = Geometry::Pointf, class F_ = SolidFill<>>
73  void Circle(Graphics::Bitmap &target, P_ location, Float radius, F_ fill = SolidFill<>(Graphics::Color::Black)) {
74  if(target.HasData())
75  Circle<S_, P_, F_>(target.GetData(), location, radius, fill);
76  }
77 
78 
84  template<int S_ = 8, class P_= Geometry::Pointf, class F_ = SolidFill<>>
85  void Circle(Containers::Image &target, P_ location, Float radius, Float border, F_ fill = SolidFill<>(Graphics::Color::Black)) {
86 
87  auto inner = radius;
88  radius += border;
89 
90  int minx = std::max((int)floor(float(location.X) - radius), 0);
91  int maxx = std::min((int)ceil(float(location.X) + radius), target.GetWidth());
92 
93  int miny = std::max((int)floor(float(location.Y) - radius), 0);
94  int maxy = std::min((int)ceil(float(location.Y) + radius), target.GetHeight());
95 
96  Float r2 = inner * inner;
97  Float br2 = radius * radius;
98 
99  if(S_ == 1) {
100  float cury = float(miny+0.5) - location.Y;
101  for(int y=miny; y<maxy; y++, cury++) {
102  float curx = float(minx+0.5) - location.X;
103  for(int x=minx; x<maxx; x++, curx++) {
104  auto d = cury*cury + curx*curx;
105  if(d < br2 && d > r2) {
106  auto cur = target.GetRGBAAt(x, y);
107 
108  target.SetRGBAAt(x, y, fill({curx, cury}, {x, y}, cur, 1.f));
109  }
110  }
111  }
112  }
113  else {
114  Float s2 = sqrt(2.0f);
115  Float ri = (inner-s2/2);
116  Float ri2 = ri * ri;
117  Float ro = (inner+s2/2);
118  Float ro2 = ro * ro;
119 
120  Float ri2br = (radius-s2/2) * (radius-s2/2);
121  Float robr = (radius+s2/2);
122  Float ro2br = robr * robr;
123 
124  Float cury = Float(miny-0.5) - location.Y;
125  for(int y=miny-1; y<maxy+1; y++, cury++) {
126  Float curx = Float(minx-0.5) - location.X;
127  for(int x=minx-1; x<maxx+1; x++, curx++) {
128  Float d = cury*cury + curx*curx;
129 
130  if(d > ro2 && d < ri2br) {
131  auto cur = target.GetRGBAAt(x, y);
132 
133  target.SetRGBAAt(x, y, fill({curx, cury}, {x, y}, cur, 1.f));
134  }
135  else if(d > ri2 && d < ro2br) {
136  auto cur = target.GetRGBAAt(x, y);
137  d = sqrt(d);
138 
139  Float a1 = (robr-d)/s2;
140  if(a1 > 1)
141  a1 = 1;
142 
143  Float a2 = (d-ri)/s2;
144  if(a2 > 1)
145  a2 = 1;
146 
147  target.SetRGBAAt(x, y, fill({curx, cury}, {x, y}, cur, a1*a2));
148  }
149  }
150  }
151  }
152  }
153 
154  template<int S_ = 8, class P_ = Geometry::Pointf, class F_ = SolidFill<>>
155  void Circle(Graphics::Bitmap &target, P_ location, Float radius, Float border, F_ fill = SolidFill<>(Graphics::Color::Black)) {
156  if(target.HasData())
157  Circle<S_, P_, F_>(target.GetData(), location, radius, border, fill);
158  }
159 
160 } }
Gorgon::CGI::SolidFill
Fills a drawing with a solid color.
Definition: CGI.h:11
Gorgon::Graphics::Color::Black
constexpr RGBA Black
Definition: Color.h:653
Gorgon::Float
float Float
Represents floating point data type.
Definition: Types.h:16
Gorgon::CGI::Circle
void Circle(Containers::Image &target, P_ location, Float radius, F_ fill=SolidFill<>(Graphics::Color::Black))
Draws a filled circle with the specified radius to the given target.
Definition: Circle.h:19
Gorgon::Containers::basic_Image::GetWidth
int GetWidth() const
Returns the width of the image.
Definition: Image.h:1296
Gorgon
Root namespace for Gorgon Game Engine.
Definition: Any.h:19
Gorgon::Graphics::Bitmap::HasData
bool HasData() const
Checks if this image resource has a data attached to it.
Definition: Bitmap.h:163
Gorgon::Graphics::Bitmap
This object contains an bitmap image.
Definition: Bitmap.h:25
Gorgon::Containers::basic_Image::SetRGBAAt
void SetRGBAAt(int x, int y, Graphics::RGBA color)
Sets the color at the given location to the specified RGBA value.
Definition: Image.h:1241
Gorgon::Containers::basic_Image
This class is a container for image data.
Definition: Image.h:19
Gorgon::Containers::basic_Image::GetHeight
int GetHeight() const
Returns the height of the image.
Definition: Image.h:1301
Gorgon::Graphics::Bitmap::GetData
Containers::Image & GetData() const
Returns the data attached to this bitmap. If no data is present, this function throws.
Definition: Bitmap.h:168
Gorgon::Containers::basic_Image::GetRGBAAt
Graphics::RGBA GetRGBAAt(int x, int y) const
Returns the alpha at the given location.
Definition: Image.h:1207