Added random color generation to the polygons, also made so that the
color of the vector indicating speed is the same as the color of the polygon, but a little lighter
This commit is contained in:
parent
79ac43f05c
commit
082acc4451
5
Makefile
5
Makefile
@ -11,7 +11,7 @@ CXXFLAGS=-Wall -g -O2 $(PROFILING_CFLAGS) $(GTK_CFLAGS)
|
||||
LIBS=$(GTK_LIBS) -lm
|
||||
|
||||
PROGS=balls
|
||||
OBJS=balls.o c_index.o game.o gravity.o spaceship.o main.o polygons.o polygon_generator.o collisions.o
|
||||
OBJS=balls.o c_index.o game.o gravity.o spaceship.o main.o polygons.o polygon_generator.o collisions.o color.o
|
||||
|
||||
# dependencies (gcc -MM *.cc)
|
||||
balls.o: balls.cc game.h balls.h vec2d.h gravity.h
|
||||
@ -21,9 +21,10 @@ gravity.o: gravity.cc gravity.h balls.h vec2d.h game.h
|
||||
main.o: main.cc game.h balls.h vec2d.h c_index.h gravity.h spaceship.h
|
||||
spaceship.o: spaceship.cc balls.h vec2d.h game.h
|
||||
stats.o: stats.cc
|
||||
polygons.o: polygons.cc polygons.h vec2d.h polygon_generator.h
|
||||
polygons.o: polygons.cc polygons.h vec2d.h polygon_generator.h color.h
|
||||
polygon_generator.o: polygon_generator.cc polygon_generator.h
|
||||
collisions.o: collisions.cc collisions.h vec2d.h
|
||||
color.o: color.cc color.h
|
||||
|
||||
|
||||
.PHONY: run
|
||||
|
102
color.cc
Normal file
102
color.cc
Normal file
@ -0,0 +1,102 @@
|
||||
#include "color.h"
|
||||
|
||||
// taken from
|
||||
// https://stackoverflow.com/questions/3018313/algorithm-to-convert-rgb-to-hsv-and-hsv-to-rgb-in-range-0-255-for-both
|
||||
hsv_t rgb2hsv(color_t in) {
|
||||
hsv_t out;
|
||||
double min, max, delta;
|
||||
|
||||
min = in.red < in.green ? in.red : in.green;
|
||||
min = min < in.blue ? min : in.blue;
|
||||
|
||||
max = in.red > in.green ? in.red : in.green;
|
||||
max = max > in.blue ? max : in.blue;
|
||||
|
||||
out.val = max; // v
|
||||
delta = max - min;
|
||||
if (delta < 0.00001) {
|
||||
out.sat = 0;
|
||||
out.hue = 0; // undefined, maybe nan?
|
||||
return out;
|
||||
}
|
||||
if (max > 0.0) { // NOTE: if Max is == 0, this divide would cause a crash
|
||||
out.sat = (delta / max); // s
|
||||
} else {
|
||||
// if max is 0, then r = g = b = 0
|
||||
// s = 0, h is undefined
|
||||
out.sat = 0.0;
|
||||
out.hue = NAN; // its now undefined
|
||||
return out;
|
||||
}
|
||||
if (in.red >= max) // > is bogus, just keeps compilor happy
|
||||
out.hue = (in.green - in.blue) / delta; // between yellow & magenta
|
||||
else if (in.green >= max)
|
||||
out.hue = 2.0 + (in.blue - in.red) / delta; // between cyan & yellow
|
||||
else
|
||||
out.hue = 4.0 + (in.red - in.green) / delta; // between magenta & cyan
|
||||
|
||||
out.hue *= 60.0; // degrees
|
||||
|
||||
if (out.hue < 0.0)
|
||||
out.hue += 360.0;
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
color_t hsv2rgb(hsv_t in) {
|
||||
double hh, p, q, t, ff;
|
||||
long i;
|
||||
color_t out;
|
||||
|
||||
if (in.sat <= 0.0) { // < is bogus, just shuts up warnings
|
||||
out.red = in.val;
|
||||
out.green = in.val;
|
||||
out.blue = in.val;
|
||||
return out;
|
||||
}
|
||||
hh = in.hue;
|
||||
if (hh >= 360.0)
|
||||
hh = 0.0;
|
||||
hh /= 60.0;
|
||||
i = (long) hh;
|
||||
ff = hh - i;
|
||||
p = in.val * (1.0 - in.sat);
|
||||
q = in.val * (1.0 - (in.sat * ff));
|
||||
t = in.val * (1.0 - (in.sat * (1.0 - ff)));
|
||||
|
||||
switch (i) {
|
||||
case 0:
|
||||
out.red = in.val;
|
||||
out.green = t;
|
||||
out.blue = p;
|
||||
break;
|
||||
case 1:
|
||||
out.red = q;
|
||||
out.green = in.val;
|
||||
out.blue = p;
|
||||
break;
|
||||
case 2:
|
||||
out.red = p;
|
||||
out.green = in.val;
|
||||
out.blue = t;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
out.red = p;
|
||||
out.green = q;
|
||||
out.blue = in.val;
|
||||
break;
|
||||
case 4:
|
||||
out.red = t;
|
||||
out.green = p;
|
||||
out.blue = in.val;
|
||||
break;
|
||||
case 5:
|
||||
default:
|
||||
out.red = in.val;
|
||||
out.green = p;
|
||||
out.blue = q;
|
||||
break;
|
||||
}
|
||||
return out;
|
||||
}
|
17
color.h
Normal file
17
color.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef COLOR_H_INCLUDED
|
||||
#define COLOR_H_INCLUDED
|
||||
|
||||
#include <cmath>
|
||||
|
||||
struct color_t {
|
||||
double red, green, blue;
|
||||
};
|
||||
|
||||
struct hsv_t {
|
||||
double hue, sat, val;
|
||||
};
|
||||
|
||||
extern hsv_t rgb2hsv(color_t in);
|
||||
extern color_t hsv2rgb(hsv_t in);
|
||||
|
||||
#endif
|
4
main.cc
4
main.cc
@ -213,6 +213,10 @@ gint keyboard_input(GtkWidget* widget, GdkEventKey* event) {
|
||||
case GDK_KEY_p:
|
||||
game_animation_on_off();
|
||||
return TRUE;
|
||||
case GDK_KEY_S:
|
||||
case GDK_KEY_s:
|
||||
draw_speed = !draw_speed;
|
||||
return TRUE;
|
||||
case GDK_KEY_Q:
|
||||
case GDK_KEY_q:
|
||||
gtk_main_quit();
|
||||
|
97
polygons.cc
97
polygons.cc
@ -13,9 +13,28 @@
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#define ARROW_VAL_RATIO 1.7
|
||||
|
||||
|
||||
bool draw_speed = true;
|
||||
|
||||
polygon* polygons = nullptr;
|
||||
uint n_polygons = 0;
|
||||
|
||||
static double to_rad(double angle_in_deg) {
|
||||
static double PI_180 = M_PI / 180.;
|
||||
return angle_in_deg * PI_180;
|
||||
}
|
||||
|
||||
static double to_deg(double angle_in_rad) {
|
||||
static double PI_180 = 180. / M_PI;
|
||||
return angle_in_rad * PI_180;
|
||||
}
|
||||
|
||||
static double random_color_component() {
|
||||
return 1.0 * (rand() % 200 + 56) / 255;
|
||||
};
|
||||
|
||||
void polygons_init_state() {
|
||||
n_polygons = 20;
|
||||
polygons = new polygon[n_polygons];
|
||||
@ -38,12 +57,19 @@ void polygons_init_state() {
|
||||
.set_mass(INFINITY)
|
||||
.set_center({width + wall_thickness / 2., height / 2.});
|
||||
|
||||
// middle wall
|
||||
polygons[n++] = poly_generate::rectangle(50, height / 2.)
|
||||
// top triangle wall
|
||||
polygons[n++] = poly_generate::triangle(height / 4., height / 4., 90)
|
||||
.set_mass(INFINITY)
|
||||
.set_center({25 + width * 1. / 2, height / 2.})
|
||||
.set_angle(30);
|
||||
.set_center({width / 2., height / 17.})
|
||||
.set_angle(-135);
|
||||
// bottom triangle wall
|
||||
polygons[n++] = poly_generate::triangle(height / 4., height / 4., 90)
|
||||
.set_mass(INFINITY)
|
||||
.set_center({width / 2., height - height / 17.})
|
||||
.set_angle(45);
|
||||
|
||||
|
||||
// ---------- Shapes flying around start here ----------
|
||||
polygons[n++] = poly_generate::regular(100, 3)
|
||||
.set_center({100, 400})
|
||||
.set_angle(0)
|
||||
@ -64,24 +90,37 @@ void polygons_init_state() {
|
||||
polygons[n++] = poly_generate::rectangle(100, 150).set_center({600, 200});
|
||||
polygons[n++] = poly_generate::regular(50, 5)
|
||||
.set_center({150, 150})
|
||||
.set_speed({50, -50});
|
||||
polygons[n++] =
|
||||
poly_generate::general({{0, 0}, {50, 80}, {0, 160}, {-50, 80}})
|
||||
.set_center({700, 700})
|
||||
.set_speed({0, -100});
|
||||
.set_speed({100, 0});
|
||||
|
||||
polygons[n++] = poly_generate::general({{40, 20},
|
||||
{40, 40},
|
||||
{80, 40},
|
||||
{80, -40},
|
||||
{40, -40},
|
||||
{40, -20},
|
||||
{-40, -20},
|
||||
{-40, -40},
|
||||
{-80, -40},
|
||||
{-80, 40},
|
||||
{-40, 40},
|
||||
{-40, 20}})
|
||||
.set_center({700, 700})
|
||||
.set_speed({0, -100});
|
||||
|
||||
assert(n <= n_polygons);
|
||||
n_polygons = n;
|
||||
}
|
||||
|
||||
static double to_rad(double angle_in_deg) {
|
||||
static double PI_180 = M_PI / 180.;
|
||||
return angle_in_deg * PI_180;
|
||||
}
|
||||
|
||||
static double to_deg(double angle_in_rad) {
|
||||
static double PI_180 = 180. / M_PI;
|
||||
return angle_in_rad * PI_180;
|
||||
// Set the color of the polygons to random
|
||||
for (polygon* p = polygons; p != polygons + n_polygons; ++p) {
|
||||
p->color = {
|
||||
random_color_component(),
|
||||
random_color_component(),
|
||||
random_color_component()};
|
||||
hsv_t hsv = rgb2hsv(p->color);
|
||||
if (hsv.val > 0.95)
|
||||
hsv.val *= .7;
|
||||
p->color = hsv2rgb(hsv);
|
||||
}
|
||||
}
|
||||
|
||||
static bool is_point_inside_rect(rect rect, vec2d point) {
|
||||
@ -252,15 +291,31 @@ void polygon::draw(cairo_t* cr) const {
|
||||
cairo_line_to(cr, point.x, point.y);
|
||||
|
||||
cairo_line_to(cr, this->global_points[0].x, this->global_points[0].y);
|
||||
cairo_stroke(cr);
|
||||
|
||||
if (mass == INFINITY) {
|
||||
cairo_set_source_rgb(cr, .5, .5, .5);
|
||||
cairo_fill(cr);
|
||||
} else {
|
||||
cairo_set_source_rgb(
|
||||
cr,
|
||||
this->color.red,
|
||||
this->color.green,
|
||||
this->color.blue
|
||||
);
|
||||
cairo_fill(cr);
|
||||
}
|
||||
|
||||
// draw centroid
|
||||
vec2d centroid = this->centroid();
|
||||
draw_circle(cr, centroid, 1);
|
||||
|
||||
|
||||
// draw speed
|
||||
(delta * this->speed).draw(cr, centroid);
|
||||
if (draw_speed && this->mass != INFINITY) {
|
||||
hsv_t hsv = rgb2hsv(this->color);
|
||||
hsv.val = hsv.val * ARROW_VAL_RATIO;
|
||||
color_t arrow_color = hsv2rgb(hsv);
|
||||
(delta * this->speed).draw(cr, centroid, arrow_color);
|
||||
}
|
||||
}
|
||||
|
||||
void polygons_draw(cairo_t* cr) {
|
||||
|
@ -1,6 +1,7 @@
|
||||
#ifndef POLYGONS_H_INCLUDED
|
||||
#define POLYGONS_H_INCLUDED
|
||||
|
||||
#include "color.h"
|
||||
#include "vec2d.h"
|
||||
|
||||
#include <cmath>
|
||||
@ -22,6 +23,7 @@ class polygon {
|
||||
double mass;
|
||||
std::string label;
|
||||
|
||||
color_t color;
|
||||
std::vector<vec2d> global_points = points;
|
||||
|
||||
vec2d speed;
|
||||
@ -118,6 +120,8 @@ class polygon {
|
||||
extern polygon* polygons;
|
||||
extern uint n_polygons;
|
||||
|
||||
extern bool draw_speed;
|
||||
|
||||
extern void polygons_init_state();
|
||||
extern void polygons_update_state();
|
||||
extern void polygons_draw(cairo_t* cr);
|
||||
|
5
vec2d.h
5
vec2d.h
@ -2,6 +2,7 @@
|
||||
#define VEC2D_H_INCLUDED
|
||||
|
||||
#include "cairo.h"
|
||||
#include "color.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
@ -74,7 +75,7 @@ class vec2d {
|
||||
return {-y, x};
|
||||
}
|
||||
|
||||
void draw(cairo_t* cr, vec2d p) const {
|
||||
void draw(cairo_t* cr, vec2d p, color_t color) const {
|
||||
double arrow_lenght_ = 10 * vec2d::norm(*this);
|
||||
double arrow_degrees_ = .5;
|
||||
|
||||
@ -90,7 +91,7 @@ class vec2d {
|
||||
double x2 = end.x + head_length * cos(angle + arrow_degrees_);
|
||||
double y2 = end.y + head_length * sin(angle + arrow_degrees_);
|
||||
|
||||
cairo_set_source_rgb(cr, 255, 0, 0);
|
||||
cairo_set_source_rgb(cr, color.red, color.green, color.blue);
|
||||
|
||||
cairo_move_to(cr, p.x, p.y);
|
||||
cairo_line_to(cr, end.x, end.y);
|
||||
|
Loading…
Reference in New Issue
Block a user