| 199 | } |
| 200 | |
| 201 | void HyperImage::conicalFill(double angle, const std::vector<uint8_t>& points, bool reset) |
| 202 | { |
| 203 | auto data = _surface.rawMem(); |
| 204 | auto h = this->height(); |
| 205 | auto w = this->width(); |
| 206 | float pi = std::atan(1) * 4; |
| 207 | |
| 208 | if (reset) |
| 209 | memset(data, 0, 3ll * w * h); |
| 210 | |
| 211 | if (points.size() < 5 || points.size() % 5) |
| 212 | return; |
| 213 | |
| 214 | for (int y = 0; y < h; y++) |
| 215 | { |
| 216 | for (int x = 0; x < w; x++) |
| 217 | { |
| 218 | ColorRgb c; |
| 219 | |
| 220 | float dx = (x - w/2); |
| 221 | float dy = (h/2 - y); |
| 222 | float len = dx * dx + dy * dy; |
| 223 | float deltaAngle = angle; |
| 224 | |
| 225 | if (len > 0.0) |
| 226 | { |
| 227 | double newAngle = atan2(1.0, 0.0) - atan2(dy, dx); |
| 228 | newAngle = newAngle * 360.0 / (2 * pi); |
| 229 | deltaAngle += newAngle; |
| 230 | } |
| 231 | |
| 232 | |
| 233 | while (deltaAngle > 360.0) |
| 234 | deltaAngle -= 360.0; |
| 235 | while (deltaAngle < 0.0) |
| 236 | deltaAngle += 360.0; |
| 237 | |
| 238 | int currentAngle = ColorRgb::clamp(std::round(deltaAngle * 255 / 360.0)); |
| 239 | |
| 240 | |
| 241 | int lastAngle = 0, lastAlfa = 0; |
| 242 | ColorRgb lastColor; |
| 243 | |
| 244 | for (size_t index = 0; index < points.size(); index += 5) |
| 245 | { |
| 246 | int nextAngle = points[index]; |
| 247 | ColorRgb nextColor = ColorRgb(points[index + 1], points[index + 2], points[index + 3]); |
| 248 | int nextAlfa = points[index + 4]; |
| 249 | |
| 250 | if (index > 0) |
| 251 | { |
| 252 | if (lastAngle <= currentAngle && currentAngle <= nextAngle) |
| 253 | { |
| 254 | float distance = nextAngle - lastAngle; |
| 255 | float aspect2 = (currentAngle - lastAngle) / distance; |
| 256 | float aspect1 = 1.0 - aspect2; |
| 257 | |
| 258 | if (nextAlfa > 0 && lastAlfa > 0) |