From 901a5f2b3c297dfe2a92ee125740e8462c079c90 Mon Sep 17 00:00:00 2001 From: Joscha Date: Thu, 18 May 2017 16:48:05 +0000 Subject: [PATCH] Add GeneTriangle Fix a few Gene type issues --- src/Genes.cpp | 148 +++++++++++++++++++++++++++++++++++--------------- src/Genes.hpp | 23 +++++--- src/main.cpp | 1 + 3 files changed, 121 insertions(+), 51 deletions(-) diff --git a/src/Genes.cpp b/src/Genes.cpp index 968fef6..0bbe8c2 100644 --- a/src/Genes.cpp +++ b/src/Genes.cpp @@ -50,6 +50,54 @@ Gene* Gene::copy(Gene* gene) } +void Gene::randomizeColor(sf::Color& color) +{ + std::uniform_int_distribution<> colordist(0, 255); + color.r = colordist(*Gene::re); + color.g = colordist(*Gene::re); + color.b = colordist(*Gene::re); + color.a = colordist(*Gene::re); +} + + +void Gene::mutateColor(sf::Color& color, float stddev) +{ + std::normal_distribution<> coldist(0, stddev); + + color.r = std::clamp(color.r + coldist(*Gene::re), 0, 255); + color.g = std::clamp(color.g + coldist(*Gene::re), 0, 255); + color.b = std::clamp(color.b + coldist(*Gene::re), 0, 255); + color.a = std::clamp(color.a + coldist(*Gene::re), 0, 255); +} + + +void Gene::randomizePosition(sf::Vector2f& position) +{ + std::uniform_real_distribution<> floatdist(0, 1); + position.x = floatdist(*Gene::re)*Gene::size.x; + position.y = floatdist(*Gene::re)*Gene::size.y; +} + + +void Gene::mutatePosition(sf::Vector2f& position, float stddev) +{ + std::normal_distribution<> posdist(0, stddev); + float min_side = std::min(Gene::size.x, Gene::size.y); + + position.x = std::clamp( + position.x + posdist(*Gene::re)*min_side, + 0, + Gene::size.x + ); + + position.y = std::clamp( + position.y + posdist(*Gene::re)*min_side, + 0, + Gene::size.y + ); +} + + Gene::~Gene() { } @@ -62,6 +110,13 @@ float GeneCircle::stddev_position = .1; // in percent of min side length float GeneCircle::stddev_radius = .1; // in percent of max radius float GeneCircle::stddev_color = 20; // absolute value + +GeneCircle::GeneCircle() +{ + this->type = Gene::Circle; +} + + GeneCircle::~GeneCircle() { } @@ -69,25 +124,20 @@ GeneCircle::~GeneCircle() void GeneCircle::draw(sf::RenderTarget& target, sf::RenderStates states) const { - this->circle.setPosition(this->position); - this->circle.setRadius(this->radius); - this->circle.setOrigin(this->radius, this->radius); - this->circle.setFillColor(this->color); - target.draw(this->circle, states); + GeneCircle::circle.setPosition(this->position); + GeneCircle::circle.setRadius(this->radius); + GeneCircle::circle.setOrigin(this->radius, this->radius); + GeneCircle::circle.setFillColor(this->color); + target.draw(GeneCircle::circle, states); } void GeneCircle::randomize() { - std::uniform_int_distribution<> colordist(0, 255); - this->color.r = colordist(*Gene::re); - this->color.g = colordist(*Gene::re); - this->color.b = colordist(*Gene::re); - this->color.a = colordist(*Gene::re); + Gene::randomizeColor(this->color); + Gene::randomizePosition(this->position); std::uniform_real_distribution<> floatdist(0, 1); - this->position.x = floatdist(*Gene::re)*Gene::size.x; - this->position.y = floatdist(*Gene::re)*Gene::size.y; this->radius = floatdist(*Gene::re)*this->maxRadius(); } @@ -98,37 +148,18 @@ void GeneCircle::mutate() switch (choicedist(*Gene::re)) { case 0: - this->mutatePosition(); + Gene::mutatePosition(this->position, GeneCircle::stddev_position); break; case 1: this->mutateRadius(); break; case 2: - this->mutateColor(); + Gene::mutateColor(this->color, GeneCircle::stddev_color); break; } } -void GeneCircle::mutatePosition() -{ - std::normal_distribution<> posdist(0, GeneCircle::stddev_position); - float min_side = std::min(Gene::size.x, Gene::size.y); - - this->position.x = std::clamp( - this->position.x + posdist(*Gene::re)*min_side, - 0, - Gene::size.x - ); - - this->position.y = std::clamp( - this->position.y + posdist(*Gene::re)*min_side, - 0, - Gene::size.y - ); -} - - void GeneCircle::mutateRadius() { std::normal_distribution<> raddist(0, GeneCircle::stddev_radius); @@ -143,17 +174,6 @@ void GeneCircle::mutateRadius() } -void GeneCircle::mutateColor() -{ - std::normal_distribution<> coldist(0, GeneCircle::stddev_color); - - this->color.r = std::clamp(this->color.r + coldist(*Gene::re), 0, 255); - this->color.g = std::clamp(this->color.g + coldist(*Gene::re), 0, 255); - this->color.b = std::clamp(this->color.b + coldist(*Gene::re), 0, 255); - this->color.a = std::clamp(this->color.a + coldist(*Gene::re), 0, 255); -} - - float GeneCircle::maxRadius() { // return std::min(Gene::size.x, Gene::size.y); @@ -163,6 +183,17 @@ float GeneCircle::maxRadius() // GeneTriangle +float GeneTriangle::stddev_position = .1; +float GeneTriangle::stddev_color = 20; +sf::VertexArray GeneTriangle::vertices(sf::Triangles, 3); + + +GeneTriangle::GeneTriangle() +{ + this->type = Gene::Triangle; +} + + GeneTriangle::~GeneTriangle() { } @@ -170,14 +201,43 @@ GeneTriangle::~GeneTriangle() void GeneTriangle::draw(sf::RenderTarget& target, sf::RenderStates states) const { + GeneTriangle::vertices[0].position = this->pos1; + GeneTriangle::vertices[1].position = this->pos2; + GeneTriangle::vertices[2].position = this->pos3; + + GeneTriangle::vertices[0].color = this->color; + GeneTriangle::vertices[1].color = this->color; + GeneTriangle::vertices[2].color = this->color; + + target.draw(GeneTriangle::vertices, states); } void GeneTriangle::randomize() { + Gene::randomizePosition(this->pos1); + Gene::randomizePosition(this->pos2); + Gene::randomizePosition(this->pos3); + Gene::randomizeColor(this->color); } void GeneTriangle::mutate() { + std::uniform_int_distribution<> choicedist(0, 3); + + switch (choicedist(*Gene::re)) { + case 0: + Gene::mutatePosition(this->pos1, this->stddev_position); + break; + case 1: + Gene::mutatePosition(this->pos2, this->stddev_position); + break; + case 2: + Gene::mutatePosition(this->pos3, this->stddev_position); + break; + case 3: + Gene::mutateColor(this->color, this->stddev_color); + break; + } } diff --git a/src/Genes.hpp b/src/Genes.hpp index 6798afe..5ca8900 100644 --- a/src/Genes.hpp +++ b/src/Genes.hpp @@ -21,6 +21,12 @@ public: static Gene* create(GeneType type); static Gene* copy(Gene* gene); + // common randomizations/mutations + static void randomizeColor(sf::Color& color); + static void mutateColor(sf::Color& color, float stddev); + static void randomizePosition(sf::Vector2f& position); + static void mutatePosition(sf::Vector2f& position, float stddev); + GeneType type; @@ -39,8 +45,7 @@ public: static float stddev_radius; static float stddev_color; - GeneType type = Gene::Circle; - + GeneCircle(); virtual ~GeneCircle(); virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; @@ -54,10 +59,7 @@ private: float radius; sf::Color color; - void mutatePosition(); void mutateRadius(); - void mutateColor(); - float maxRadius(); }; @@ -66,8 +68,10 @@ private: class GeneTriangle : public Gene { public: - GeneType type = Gene::Triangle; + static float stddev_position; + static float stddev_color; + GeneTriangle(); virtual ~GeneTriangle(); virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const; @@ -75,5 +79,10 @@ public: virtual void mutate(); private: - // TODO: vertices + static sf::VertexArray vertices; + + sf::Vector2f pos1; + sf::Vector2f pos2; + sf::Vector2f pos3; + sf::Color color; }; diff --git a/src/main.cpp b/src/main.cpp index c0bc057..e34324f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,7 @@ int main() randomEngine.seed(time(nullptr)); Chromosome::allowGeneType(Gene::Circle); + Chromosome::allowGeneType(Gene::Triangle); Chromosome::re = &randomEngine; Gene::re = &randomEngine;