Welcome to Software Development on Codidact!
Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.
Post History
Building a Nannou App from their template. I want a circle to slowly fade in color and randomly change color when hitting the boundary of the window. But there is something strange going on when ...
#4: Post edited
Object lightness and colour strange change in Nannou application
- Strange change of object lightness and colour in Nannou application
#3: Post edited
Strange behaviour in Nannou app
- Object lightness and colour strange change in Nannou application
#2: Post edited
- Building a [Nannou App](https://nannou.cc/) from their [template](https://github.com/nannou-org/nannou/blob/master/examples/templates/template_app.rs).
- I want a circle to slowly fade in color and randomly change color when hitting the boundary of the window. But there is something strange going on when updating the colors.
- My preamble looks like this:
- use nannou::prelude::*;
- use rand::Rng;
- The model consists of a `circle` and a `boundary`.
- struct Model {
- // so this is a window id called _window -- I guess.
- _window: window::Id,
- circle: Circle,
- boundary: Boundary,
- }
- The `boundary` is just the outline of the application window and the `circle` has a diameter, position, velocity and color.
- struct Boundary {
- x_min: f32,
- x_max: f32,
- y_min: f32,
- y_max: f32,
- }
- struct Circle {
- d: f32, // diameter
- center: Point2,
- vel: Point2,
- color: Hsl,
- }
- Here is my model function:
- fn model(app: &App) -> Model {
- let _window = app.new_window().size(512, 512).view(view).build().unwrap();
- // add the coordinates to a struct and add it to the model
- let circle = Circle {
- d: 50.0,
- center: pt2(-50.0, 167.0),
- vel: pt2(1.3, -0.9),
- color: hsl(154.1, 100.0, 85.0),
- };
- let boundary = Boundary {
- x_min: app.window_rect().x.start,
- x_max: app.window_rect().x.end,
- y_min: app.window_rect().y.start,
- y_max: app.window_rect().y.end,
- };
- Model {
- _window,
- circle,
- boundary,
- }
- }
- I want three things to happen:
- * The `circle` to bounce off of the `boundary`. (This works)
- * The lightness of the color of the circle to slowly reduce at every time step.(Not Working)
- * The color of the `circle` to randomly change whenever the circle hits the wall(seems to work for a split second)
- This is how I update the model:
- fn update(_app: &App, _model: &mut Model, _update: Update) {
- // move circle by velocity
- _model.circle.center.x += _model.circle.vel.x;
- _model.circle.center.y += _model.circle.vel.y;
- // update color
- _model.circle.update_color();
- // bounce of the wall
- _model.circle.bounce_wall(&_model.boundary);
- }
- I created the `update_color` and `bounce_wall` functions for my `Circle`:
- impl Circle {
- fn update_color(&mut self) {
- let mut newlight = self.color.lightness - 0.1;
- if newlight < 0.0 {
- newlight = 0.0;
- }
- self.color = hsl(
- self.color.hue.to_positive_degrees(),
- self.color.saturation,
- newlight,
- );
- }
- fn bounce_wall(&mut self, boundary: &Boundary) {
- // all the random number stuff is stolen from
- // https://rust-lang-nursery.github.io/rust-cookbook/algorithms/randomness.html
- let mut rng = rand::thread_rng(); // rng = random number generator
- if self.center.x + 0.5 * self.d > boundary.x_max
- || self.center.x - 0.5 * self.d < boundary.x_min
- {
- self.color = hsl(rng.gen_range(0.0..360.0), rng.gen_range(0.0..100.0), 85.0);
- self.vel.x = -self.vel.x;
- }
- if self.center.y + 0.5 * self.d > boundary.y_max
- || self.center.y - 0.5 * self.d < boundary.y_min
- {
- self.color = hsl(rng.gen_range(0.0..360.0), rng.gen_range(0.0..100.0), 85.0);
- self.vel.y = -self.vel.y;
- }
- }
- }
- My `view` function looks like this:
- fn view(app: &App, _model: &Model, frame: Frame) {
- let draw = app.draw();
- draw.background().color(GRAY);
- println!(
- "new color lightness is ({})",
- _model.circle.color.into_components().2
- );
- let ellipse = draw.ellipse();
- ellipse
- .color(_model.circle.color)
- .x_y(_model.circle.center.x, _model.circle.center.y)
- .w(_model.circle.d)
- .h(_model.circle.d);
- draw.to_frame(app, &frame).unwrap();
- }
- Here is what is happening that I do not understand:
- * The lightness of the circle that the `view` function prints to the command line does go down but the color of the `circle` does not change at all. Why?
- * When bouncing of a wall, the color of the `circle` visibly changes for a very brief moment to some random color but then goes back to the initial color. So it works but is reset somehow?
* When I remove the random color changing from the `bounce_wall()` function, the color of the circle switches to black once lightness reaches `0`. So only changing the color to black is permanent?
- Building a [Nannou App](https://nannou.cc/) from their [template](https://github.com/nannou-org/nannou/blob/master/examples/templates/template_app.rs).
- I want a circle to slowly fade in color and randomly change color when hitting the boundary of the window. But there is something strange going on when updating the colors.
- My preamble looks like this:
- use nannou::prelude::*;
- use rand::Rng;
- The model consists of a `circle` and a `boundary`.
- struct Model {
- // so this is a window id called _window -- I guess.
- _window: window::Id,
- circle: Circle,
- boundary: Boundary,
- }
- The `boundary` is just the outline of the application window and the `circle` has a diameter, position, velocity and color.
- struct Boundary {
- x_min: f32,
- x_max: f32,
- y_min: f32,
- y_max: f32,
- }
- struct Circle {
- d: f32, // diameter
- center: Point2,
- vel: Point2,
- color: Hsl,
- }
- Here is my model function:
- fn model(app: &App) -> Model {
- let _window = app.new_window().size(512, 512).view(view).build().unwrap();
- // add the coordinates to a struct and add it to the model
- let circle = Circle {
- d: 50.0,
- center: pt2(-50.0, 167.0),
- vel: pt2(1.3, -0.9),
- color: hsl(154.1, 100.0, 85.0),
- };
- let boundary = Boundary {
- x_min: app.window_rect().x.start,
- x_max: app.window_rect().x.end,
- y_min: app.window_rect().y.start,
- y_max: app.window_rect().y.end,
- };
- Model {
- _window,
- circle,
- boundary,
- }
- }
- I want three things to happen:
- * The `circle` to bounce off of the `boundary`. (This works)
- * The lightness of the color of the circle to slowly reduce at every time step.(Not Working)
- * The color of the `circle` to randomly change whenever the circle hits the wall(seems to work for a split second)
- This is how I update the model:
- fn update(_app: &App, _model: &mut Model, _update: Update) {
- // move circle by velocity
- _model.circle.center.x += _model.circle.vel.x;
- _model.circle.center.y += _model.circle.vel.y;
- // update color
- _model.circle.update_color();
- // bounce of the wall
- _model.circle.bounce_wall(&_model.boundary);
- }
- I created the `update_color` and `bounce_wall` functions for my `Circle`:
- impl Circle {
- fn update_color(&mut self) {
- let mut newlight = self.color.lightness - 0.1;
- if newlight < 0.0 {
- newlight = 0.0;
- }
- self.color = hsl(
- self.color.hue.to_positive_degrees(),
- self.color.saturation,
- newlight,
- );
- }
- fn bounce_wall(&mut self, boundary: &Boundary) {
- // all the random number stuff is stolen from
- // https://rust-lang-nursery.github.io/rust-cookbook/algorithms/randomness.html
- let mut rng = rand::thread_rng(); // rng = random number generator
- if self.center.x + 0.5 * self.d > boundary.x_max
- || self.center.x - 0.5 * self.d < boundary.x_min
- {
- self.color = hsl(rng.gen_range(0.0..360.0), rng.gen_range(0.0..100.0), 85.0);
- self.vel.x = -self.vel.x;
- }
- if self.center.y + 0.5 * self.d > boundary.y_max
- || self.center.y - 0.5 * self.d < boundary.y_min
- {
- self.color = hsl(rng.gen_range(0.0..360.0), rng.gen_range(0.0..100.0), 85.0);
- self.vel.y = -self.vel.y;
- }
- }
- }
- My `view` function looks like this:
- fn view(app: &App, _model: &Model, frame: Frame) {
- let draw = app.draw();
- draw.background().color(GRAY);
- println!(
- "new color lightness is ({})",
- _model.circle.color.into_components().2
- );
- let ellipse = draw.ellipse();
- ellipse
- .color(_model.circle.color)
- .x_y(_model.circle.center.x, _model.circle.center.y)
- .w(_model.circle.d)
- .h(_model.circle.d);
- draw.to_frame(app, &frame).unwrap();
- }
- Here is what is happening that I do not understand:
- * The lightness of the circle that the `view` function prints to the command line does go down but the color of the `circle` does not change at all. Why?
- * When bouncing of a wall, the color of the `circle` visibly changes for a very brief moment to some random color but then goes back to the initial color. So it works but is reset somehow?
- * When I remove the random color changing from the `bounce_wall()` function, the color of the circle switches to black once lightness reaches `0`. So only changing the color to black is permanent?
- Edit: Thanks to comments by [elgonzo](https://software.codidact.com/users/53305) the solution was quite easy.
- [hsl](https://docs.rs/nannou/0.17.1/nannou/prelude/fn.hsl.html) expects the first component (hue) to be in `[0.0, 1.0]` instead of `[0.0, 360.0]` and the third components (lightness) to be in `[0.0, 1.0]` instead of `[0.0, 100.0]`.
- So providing a lightness value that is slowly reducing from `1.0` is creating the effect I wanted.
#1: Initial revision
Strange behaviour in Nannou app
Building a [Nannou App](https://nannou.cc/) from their [template](https://github.com/nannou-org/nannou/blob/master/examples/templates/template_app.rs). I want a circle to slowly fade in color and randomly change color when hitting the boundary of the window. But there is something strange going on when updating the colors. My preamble looks like this: use nannou::prelude::*; use rand::Rng; The model consists of a `circle` and a `boundary`. struct Model { // so this is a window id called _window -- I guess. _window: window::Id, circle: Circle, boundary: Boundary, } The `boundary` is just the outline of the application window and the `circle` has a diameter, position, velocity and color. struct Boundary { x_min: f32, x_max: f32, y_min: f32, y_max: f32, } struct Circle { d: f32, // diameter center: Point2, vel: Point2, color: Hsl, } Here is my model function: fn model(app: &App) -> Model { let _window = app.new_window().size(512, 512).view(view).build().unwrap(); // add the coordinates to a struct and add it to the model let circle = Circle { d: 50.0, center: pt2(-50.0, 167.0), vel: pt2(1.3, -0.9), color: hsl(154.1, 100.0, 85.0), }; let boundary = Boundary { x_min: app.window_rect().x.start, x_max: app.window_rect().x.end, y_min: app.window_rect().y.start, y_max: app.window_rect().y.end, }; Model { _window, circle, boundary, } } I want three things to happen: * The `circle` to bounce off of the `boundary`. (This works) * The lightness of the color of the circle to slowly reduce at every time step.(Not Working) * The color of the `circle` to randomly change whenever the circle hits the wall(seems to work for a split second) This is how I update the model: fn update(_app: &App, _model: &mut Model, _update: Update) { // move circle by velocity _model.circle.center.x += _model.circle.vel.x; _model.circle.center.y += _model.circle.vel.y; // update color _model.circle.update_color(); // bounce of the wall _model.circle.bounce_wall(&_model.boundary); } I created the `update_color` and `bounce_wall` functions for my `Circle`: impl Circle { fn update_color(&mut self) { let mut newlight = self.color.lightness - 0.1; if newlight < 0.0 { newlight = 0.0; } self.color = hsl( self.color.hue.to_positive_degrees(), self.color.saturation, newlight, ); } fn bounce_wall(&mut self, boundary: &Boundary) { // all the random number stuff is stolen from // https://rust-lang-nursery.github.io/rust-cookbook/algorithms/randomness.html let mut rng = rand::thread_rng(); // rng = random number generator if self.center.x + 0.5 * self.d > boundary.x_max || self.center.x - 0.5 * self.d < boundary.x_min { self.color = hsl(rng.gen_range(0.0..360.0), rng.gen_range(0.0..100.0), 85.0); self.vel.x = -self.vel.x; } if self.center.y + 0.5 * self.d > boundary.y_max || self.center.y - 0.5 * self.d < boundary.y_min { self.color = hsl(rng.gen_range(0.0..360.0), rng.gen_range(0.0..100.0), 85.0); self.vel.y = -self.vel.y; } } } My `view` function looks like this: fn view(app: &App, _model: &Model, frame: Frame) { let draw = app.draw(); draw.background().color(GRAY); println!( "new color lightness is ({})", _model.circle.color.into_components().2 ); let ellipse = draw.ellipse(); ellipse .color(_model.circle.color) .x_y(_model.circle.center.x, _model.circle.center.y) .w(_model.circle.d) .h(_model.circle.d); draw.to_frame(app, &frame).unwrap(); } Here is what is happening that I do not understand: * The lightness of the circle that the `view` function prints to the command line does go down but the color of the `circle` does not change at all. Why? * When bouncing of a wall, the color of the `circle` visibly changes for a very brief moment to some random color but then goes back to the initial color. So it works but is reset somehow? * When I remove the random color changing from the `bounce_wall()` function, the color of the circle switches to black once lightness reaches `0`. So only changing the color to black is permanent?