How to make a color changing sky in Racket? - racket

I have a variable that controls the number of blue in (color R, G, B). Now I am confused about how to use that variable in (color R, G, B). Also, I am totally new to Racket. I know I can combine these functions together, but I don't know how :( The purpose of this code is to make a color changing scene in animate.
Here is my code:
(require 2htdp/image)
(define(Skycolor num)
(remainder num 510))
(define(skycolor num)
(abs(- 255(Skycolor num))))
(define(sky-color num)
(color 0 0 (skycolor num)))
(define (SKY num )
(square 200 "solid" (color 0 0 (sky-color num)))))

It's not very clear what do you mean with "color changing", but you can take some inspiration from following code. See also this similar question, where I explain how animate works.
#lang racket
(require 2htdp/universe)
(require 2htdp/image)
(define speed 5)
(define (sky-color ticks)
(color 0 (modulo (* speed (- 255 ticks)) 255) 255))
(define bg
(empty-scene 125 125))
(define (make-sky ticks)
(square 250 "solid" (sky-color ticks)))
(define (draw-image ticks)
(place-image (make-sky ticks) 0 0 bg))
(animate draw-image)

Related

Racket/Beginner Student Language Confusion

I am trying to animate the word "floccinaucinihilipilification" letter by letter. Right now it displays the complete word in the animation window, but I am lost on how to animate it so it will count up from the first character to the last, looping back to 0.
(define LONG-WORD "floccinaucinihilipilification")
; cycle-spelling : String -> Image
; display an animation of a long
; word being spelled out
(define a (string-length LONG-WORD))
(define TXT
(text (substring LONG-WORD 0 a) 30 "black"))
(define BG
(empty-scene 400 400))
(define (cycle-spelling a)
(place-image TXT 200 200 BG))
(animate cycle-spelling)
See what animate does:
(animate create-image) → natural-number/c
create-image : (-> natural-number/c scene?)
opens a canvas and starts a clock that ticks 28 times per second. Every time the clock ticks, DrRacket applies create-image to the number of ticks passed since this function call. The results of these function calls are displayed in the canvas. The simulation runs until you click the Stop button in DrRacket or close the window. At that point, animate returns the number of ticks that have passed.
So you have to base your code on the number of ticks, passed to create-image function.
(animate cycle-spelling)
(define (cycle-spelling ticks) ... )
Start with (quotient ticks 28), value of this expression increases each second by 1.
Looping is created with modulo, so after some experimenting, you should have something like this:
(modulo (quotient ticks 28) (+ (string-length long-word) 1))
Rest of the code will be similar.
Following code animates given word letter by letter and then loops back to 0.
#lang racket
(require 2htdp/universe)
(require 2htdp/image)
(define long-word "floccinaucinihilipilification")
(define speed 3) ; try also 7, 14, 28 ...
(define bg
(empty-scene 400 400))
(define (cycle-spelling ticks)
(place-image (text (substring long-word 0
(modulo (quotient ticks speed)
(+ (string-length long-word) 1)))
30 "black")
200 200 bg))
(animate cycle-spelling)

What makes my image look half as wide as intended?

I am trying to place a vertically positioned rectangle and another object on an empty-scene using place-images in Beginning Student Language. However, when I run the function, the rectangle only takes up half the scene horizontally when its width is set equal to the width of the scene.
I checked what happens to my code using Stepper and found where the image-width halves but I do not know why. Probably it's to do with cons which I am not very familiar with.
Here's the full code:
(require 2htdp/image)
(define WIDTH 400)
(define HEIGHT 300)
(define HMAX 100)
(define SCENE (empty-scene WIDTH HEIGHT))
(define-struct vcham [x h c])
(define c (make-vcham 0 100 "white"))
(define (render ch)
(place-images (list (rectangle (* 1 WIDTH (/ (vcham-h ch) HMAX)) 50 "solid" "maroon")
(rectangle 1 1 "solid" "blue"))
(list (make-posn 0 0) (make-posn 20 20))
SCENE))
(render c)
I have simplified this code as much as a I could, thus the 1×1 rectangle. I am also interested in elegant alternatives to implement this, but am most interested in finding out why this happens.
place-images is like place-image :
Places image onto scene with its center at the coordinates (x,y)
and crops the resulting image so that it has the same size as
scene. The coordinates are relative to the top-left of scene.
you can change (make-posn 0 0) to (make-posn 200 25), or try place-images/align
(define (render ch)
(place-images/align (list (rectangle (* 1 WIDTH (/ (vcham-h ch) HMAX)) 50 "solid" "maroon")
(rectangle 1 1 "solid" "blue"))
(list (make-posn 0 0) (make-posn 20 20))
"left" "top" SCENE))

How to filter random number generator and not include 0

How do I fix the random: expects (or/c (integer-in 1 4294967087) pseudo-random-generator?) or a pseudo-random-generator, given 0 error?
(require 2htdp/universe)
(require 2htdp/image)
(define-struct sample(x))
(define BACKGROUND (empty-scene 100 100))
(define CIRCLE (ellipse 10 10 "solid" "red"))
(define (rand d)
(random d))
(define (randoll d)
(cond [(even? (rand d))(rand d)]
[(< (rand d) 6)7]
[(= (rand d) 0)7]
[else 7]))
(define (main ws)
(big-bang ws
(on-tick randoll)
(to-draw render)))
(define (render d)
(place-image CIRCLE (randoll d) 6 BACKGROUND))
(main 100)
random: expects (or/c (integer-in 1 4294967087) pseudo-random-generator?) or a pseudo-random-generator, given 0
Was expecting for it to continuously changing places at even numbers but this happened
How about adding 1 to the parameter passed to random? as long as the input is >= 0 it'll work fine - the error you're receiving is simply stating that you can't pass 0 as parameter to random:
(define (rand d)
(random (+ d 1)))
By the way, randoll doesn't look right. Why do you test if the random value is even, just to return another random value, which we don't know if it's going to be even? And it appears that if the random value is zero or in all the other cases you just want to return 7. Better try this, if it fits what you intended:
(define (randoll d)
(let ([r (rand d)]) ; call `rand` exactly once
(cond [(zero? r) 7] ; 0 is even, so check this first
[(even? r) r] ; return `r` only if it's even
[else 7]))) ; default case
I'm not sure what's the expected range of values for randoll, but it looks to me that most of the time it'll just return 7. Is this what you want?

How to paint on previous picture in the functional way in Racket

This code maintains number of ticks, but all ways paints on a new screen
#lang racket
(require 2htdp/universe)
(require 2htdp/image)
(define pasaulis (empty-scene 100 100))
(define (trace-circle t)
(place-image (circle 5 "solid" "blue")
(+ 50(* 40 (cos (/ t 100))))
(+ 50(* 40 (sin (/ t 100))))
pasaulis))
(define (render t)
(text (number->string t) 12 "red"))
(big-bang 1000000
(on-tick sub1 1/500)
(to-draw trace-circle)
(stop-when zero?)
(record? true))
The following code does maintain picture, but I could not have number of ticks passed to the pain handler.
#lang racket
(require 2htdp/universe)
(require 2htdp/image)
(require picturing-programs)
(define (move-right-10 picture)
(beside (rectangle 10 0 "solid" "white")
picture))
(big-bang pic:calendar
(on-draw show-it 500 100)
(on-tick move-right-10 1/22))
I just cannot figure it out. how to have draw function with number of ticks, while modifying the screen. Is the big-bang function suitable at all for the purpose?
Here is an example:
#lang racket
(require 2htdp/universe)
(require 2htdp/image)
(struct world (ticks pic))
(define pasaulis (empty-scene 1000 1000))
(define (render w)
(world-pic w))
(define (handle-on-tick w)
(define t (world-ticks w))
(define p (world-pic w))
(define new-ticks (+ t 1))
(define new-pic (overlay/xy (text (number->string t) 12 "red")
(* -10 t) (* -10 t)
p))
(world new-ticks new-pic))
(define (stop? w)
(= (world-ticks w) 50))
(big-bang (world 0 pasaulis)
(on-tick handle-on-tick 1/5)
(to-draw render)
(stop-when stop?))

Smoother projectile motion in Racket?

I'm playing a little with Racket big-bang mechanism, but I cannot get both smooth and fast going projectile. There's so much ugly flickering. Here's my code:
(require 2htdp/universe
2htdp/image)
(define gx 0)
(define gy 0.35)
(struct ballstate (x y vx vy) #:transparent)
(define startstate (ballstate 10 590 7 -20))
(define (make-new-state old)
(define newvx (+ (ballstate-vx old) gx))
(define newvy (+ (ballstate-vy old) gy))
(ballstate (+ (ballstate-x old) newvx)
(+ (ballstate-y old) newvy)
newvx
newvy))
(define (main)
(big-bang startstate
[on-tick make-new-state]
[to-draw place-ball-at]
[on-key reset]))
(define (place-ball-at s)
(place-image (circle 10 "solid" "red")
(ballstate-x s)
(ballstate-y s)
(empty-scene 800 600)))
(define (reset s ke)
startstate)
(main)
The question is: how to make it better, faster, smoother and flicker-free?
Here are two things that might help:
The on-tick clause takes an optional parameter that determines the time between two ticks. The default is 1/28, so if you lower this you will get more frames resulting in a smoother animation.
If your program takes longer than the time between each tick to produce an image, you will see stuttering. Precomputing everything that can be precomputed is a good thing. For example, there is no reason to produce a new empty scene each time, so below I have simply stored it in a variable.
(define (main)
(big-bang startstate
[on-tick make-new-state 1/50]
[to-draw place-ball-at]
[on-key reset]))
(define background (empty-scene 800 600))
(define (place-ball-at s)
(place-image (circle 10 "solid" "red")
(ballstate-x s)
(ballstate-y s)
background))