#pragma once #include #include #include #include #include #include "Random.h" #include "Ray.h" template inline T getRandomNumber(U min, V max) { return static_cast(Random::get(min, max)); } template inline sf::Color createColor(T r, U g, V b, W a) { return sf::Color(static_cast(r), static_cast(g), static_cast(b), static_cast(a)); } template inline sf::Color createColor(T r, U g, V b, std::uint8_t a = 255u) { return sf::Color(static_cast(r), static_cast(g), static_cast(b), a); } inline sf::Color getRandomColor() { return sf::Color(getRandomNumber(0u, 255u), getRandomNumber(0u, 255u), getRandomNumber(0u, 255u)); } template inline T signage(T in) { T zero{}; if (in > zero) return ++zero; if (in < zero) return --zero; return zero; } struct LineSegment { sf::Vector2f startPoint{}; sf::Vector2f endPoint{}; }; struct imguiColor { float r{}; float g{}; float b{}; float a{ 1.f }; sf::Color asSfColor() { return sf::Color(std::uint8_t(r * 255.f), std::uint8_t(g * 255.f), std::uint8_t(b * 255.f), std::uint8_t(a * 255.f)); } }; inline imguiColor constructImguiColor(sf::Color color) { return imguiColor((float)color.r / 255.f, (float)color.g / 255.f, (float)color.b / 255.f, (float)color.a / 255.f); } inline std::optional lineIntersect(LineSegment first, LineSegment second) { sf::Vector2f firstVector = (first.endPoint - first.startPoint); sf::Vector2f secondVector = (second.endPoint - second.startPoint); float lengthCrossProduct = firstVector.cross(secondVector); sf::Vector2f fms = second.startPoint - first.startPoint; //first line start point minus second float firstScalar = fms.cross(secondVector) / lengthCrossProduct; float secondScalar = fms.cross(firstVector) / lengthCrossProduct; if ((firstScalar >= 0 and firstScalar <= 1) and (secondScalar >= 0 and secondScalar <= 1)) return sf::Vector2f(first.startPoint.x + (firstScalar * firstVector.x), first.startPoint.y + (firstScalar * firstVector.y)); else return std::nullopt; } inline sf::VertexArray constructRectangle(sf::Vector2f center, sf::Vector2f size, sf::Color color = sf::Color::Black) { sf::VertexArray rectangle(sf::PrimitiveType::LineStrip, 5); rectangle[0].color = color; rectangle[1].color = color; rectangle[2].color = color; rectangle[3].color = color; rectangle[4].color = color; rectangle[0].position = { center.x - size.x, center.y - size.y }; rectangle[1].position = { center.x + size.x, center.y - size.y }; rectangle[2].position = { center.x + size.x, center.y + size.y }; rectangle[3].position = { center.x - size.x, center.y + size.y }; rectangle[4].position = rectangle[0].position; return rectangle; } inline sf::Vector2f constructVector(sf::Vector2f startPoint, sf::Angle angle, float length) { return { startPoint.x + (length * std::cos(angle.asRadians())), startPoint.y + (length * std::sin(angle.asRadians())) }; } inline sf::VertexArray constructRandomPolygon(sf::Vector2f center, int vertexLowerBound, int vertexUpperBound, int averageSize, sf::Color color = sf::Color::Black) { std::size_t vertexCount = getRandomNumber(vertexLowerBound, vertexUpperBound); sf::VertexArray polygon(sf::PrimitiveType::LineStrip, vertexCount); float angleIncrement = 360.f / (float)(vertexCount - 1); float angleStart = getRandomNumber(0, 360); for (int i = 0; i < vertexCount - 1; i++) { float angleOffset = getRandomNumber(-(90 / (int)vertexCount), (90 / (int)vertexCount)); polygon[i].color = color; polygon[i].position = constructVector(center, sf::degrees(angleStart + (angleIncrement * i) + angleOffset), getRandomNumber((averageSize - 50), (averageSize + 50))); } polygon[vertexCount - 1].position = polygon[0].position; polygon[vertexCount - 1].color = color; return polygon; } inline float distanceBetween(sf::Vector2f startPoint, sf::Vector2f endPoint) { return sqrtf(powf(endPoint.x - startPoint.x, 2) + powf(endPoint.y - startPoint.y, 2)); } inline sf::VertexArray constructVertexArray(sf::Shape& shape) { sf::VertexArray result(sf::PrimitiveType::LineStrip); auto& transform = shape.getTransform(); for (int i = 0; i < shape.getPointCount(); i++) { result.append(sf::Vertex{ transform.transformPoint(shape.getPoint(i)), sf::Color::Black }); } result.append(result[0]); return result; }