Python 3D Graphics Tutorial 11: Improved Color Orb With Constant Brightness

preview_player
Показать описание
You guys can help me out over at Patreon, and that will help me keep my gear updated, and help me keep this quality content coming:

In this video we show step-by-step instructions on how to program an orb with a smooth and continuous change of color. This is the solution to the homework I gave you in Lesson 10 in this series. We show how to create a mesmerizing orb that smoothly transitions through a range of colors. In this example, we mathematically increment the colors to maintain constant brightness. I do not assume you are an expert, so these lessons are designed for complete beginners.
#Python
#Lessons
#Graphics
Рекомендации по теме
Комментарии
Автор

I am legend. Without the hint I used my original orb program and added a section that added the r, g, b channels and compared them to 2. Then divided by 3 and added that to the 3 channels to keep color at constant 2. With the hint I folded up. As soon as I saw you draw the triangle wave form I stopped the video and had the orb running in 10 minutes.

petefontana
Автор

I actually thought it would be even simpler than that! I was toying with "if R+G+B<2: reverse the lowest value" but I couldn't get that to work.

wayneswan
Автор

I AM LEGEND! I used a for loop with 256X3 steps, and changed the increments at the appropriate step count. Of course we only need to compute the values for two of the colors, then the third color value is (2 - the sum of those colors). Thanks again for all these great lessons, Paul.

cbrombaugh
Автор

I am Legend! Thank you, Paul, for your wonderful lessons and your very kind explanations. To do my homework, I used list indices, so the code is very short, but I think the result is the same :

myOrb = sphere(radius=1)

listChan = [1, 1, 0]
inc = .001

def shade(incChan, decChan):
while listChan[incChan] + inc < 1:
rate(250)
listChan[incChan] += inc
listChan[decChan] -= inc
myOrb.color = vector(*listChan)

while True:
for indChan in ((2, 1), (1, 0), (0, 2)):
shade(*indChan)

jeas
Автор

I AM LEGEND. Your version was however much simpler and more elegant!

berryblades
Автор

Thank you Paul! Arduino monitoring here we come!

vaughntaylor
Автор

Hello Paul, I was able to do this challenge, my code is more complicated than yours, but it still works. This is the logic part :
While True:
rate(250)
if rChan == 1:
for num in range(0, 1001, 1):
rate(250)
gChan = num / 1000
bChan = 1 - (num / 1000)
myOrb.color = vector(rChan, gChan, bChan)

if gChan == 1:
for num in range(0, 1001, 1):
rate(250)
bChan = num / 1000
rChan = 1 - (num / 1000)
myOrb.color = vector(rChan, gChan, bChan)

if bChan == 1:
for num in range(0, 1001, 1):
rate(250)
gChan = 1 - (num / 1000)
rChan = num / 1000
myOrb.color = vector(rChan, gChan, bChan)

Thank you!

marcoboi
Автор

Great Lesson Paul. You are doing a fantastic service for our youth !!!
My only comment is that in your code you cannot see the pure red, green, and blue color. Just mixture.
I was able to do it this way:
from vpython import *

ball = sphere(radius=1.0)
r =0.
g =0.
b = 0.
step = 0.001
c = 0.
d = 1.
while True:
rate(50)

if (c >= 0. and c <= 0.1667):
r = 1.
g = c/0.1667
b = 0.
total = r + g + b
rc = 2. * (r / total)
gc = 2. * (g / total)
bc = 2. * (b / total)

if (c >= 0.1667 and c <= .3333):
c1 = c - 0.1667
r = 1. - c1/0.1667
g = 1.
b = 0
total = r + g + b
rc = 2. * (r / total)
gc = 2. * (g / total)
bc = 2. * (b / total)


if (c >= 0.3333 and c <= 0.5):
c1 = c - 0.3333
r= 0.
g = 1.
b = c1/0.1667
total = r + g + b
rc = 2. * (r / total)
gc = 2. * (g / total)
bc = 2. * (b / total)

if (c >= 0.5 and c <= 0.6667):
c1 = c - 0.5
r= 0.
g = 1. - c1/0.1667
b = 1.
total = r + g + b
rc = 2. * (r / total)
gc = 2. * (g / total)
bc = 2. * (b / total)

if (c >= 0.6667 and c <= 0.8333):
c1 = c - 0.6667
r= c1/0.1667
g = 0.
b = 1.
total = r + g + b
rc = 2. * (r / total)
gc = 2. * (g / total)
bc = 2. * (b / total)

if (c >= 0.8333 and c <= 1.0):
c1 = c - 0.8333
r= 1.0
g = 0.
b = 1. - c1/0.1667
total = r + g + b
rc = 2. * (r / total)
gc = 2. * (g / total)
bc = 2. * (b / total)

ball.color = vector(rc, gc, bc)
c += step
if (c >= 1.):
c = 0.

but it is more complicated.

Again great job. I am a great fan.
RLR
Phoenix, Az.

reyrodriguez
Автор

Awesome lesson! I did it a little differently, solved the equation: oldChan/(r+g+b)=newChan/2 and solved for newChan

ellerycadel
Автор

I folded up, but this explanation amazes me, thank you Paul!

patfacunla
Автор

This was super elegant Paul.
i did it by starting a counter and the 3 channels changed according to the value of the counter. Worked exactly as i wanted it to.
it was simple too but yours is super elegant. The geometry came so handy. Thanks yet again

zaqk
Автор

The Return of the Son of Cheap Lawn Chair

RobVollmar
Автор

Thanks Paul for all you do. These lessons keep me young.

waltmetcalf
Автор

Hi Paul, my version was much more complicated than your version. I used gradients and time and all sorts of rubbish. It worked but it was not anywhere as nice a solution as yours is.
Thanks for another great learning experience.

alfredcalleja
Автор

I am Legend although it took a couple of hours. I took your diagram quite literally and based my approach on pegging the value of a particular channel at a value of 1 until the next channel reached the same value. At this point the first channel was allowed to decrement while the second channel was pegged at 1 until the next channel arrived at a value of 1. Rinse an repeat.
I did use the same starting values for the various channel increments and channel values as you did. My solution didn't take much more code than yours so I'm calling it 'moderately' elegant

#Modify the colorOrb sample program to make the overall brightness a constant
# value where the sum of the r+g+b is constantly = 2.

from vpython import *
myOrb=sphere(radius=1, color=color.white)
rChan=1
gChan=1
bChan=0
rInc=.001
gInc=-.001
bInc=.001

while True:
rate(250)
myOrb.color=vector(rChan, gChan, bChan)

# Reverse the rInc value at the top of the cycle when the blue channel reaches the
# same value as the red channel.
# The value of rChan is held at 1 until the blue channel catches up
if rChan>=1 and bChan>=1:
rInc=rInc*(-1)
# Decrement rChan at this point to allow the following condition to continue
# to apply the -ve increment on the downwards side of the cycle.
rChan=rChan+rInc
# Only apply +ve increment up to a value of 1, if the direction of the increment
# has been changed in the previous conditional statement then rChan will decrement

if rChan<1:
rChan=rChan+rInc
# At the bottom of the cycle, reverse rInc to allow increasing values of rChan
if rChan<=0:
rInc=rInc*(-1)

if gChan>=1 and rChan>=1:
gInc=gInc*(-1)
gChan=gChan+gInc
if gChan<1:
gChan=gChan+gInc
if gChan<=0:
gInc=gInc*(-1)

if bChan>=1 and gChan>=1:
bInc=bInc*(-1)
bChan=bChan+bInc
if bChan<1:
bChan=bChan+bInc
if bChan<=0:
bInc=bInc*(-1)

print('ColorTot= ', rChan+gChan+bChan)

martinjones
Автор

I am very good on the electro/mechanical side of problem solving but some of these logic problems have been stumping me. Will keep at it as it is a weakness that needs improvement. Thanks Paul for keeping the brain cobwebs at bay 😎... No cat videos here..

justmc
Автор

my solution was good i think without any unnecessary variables
import vpython

orb = vpython.sphere()
R = 0
G = 1
B = 1
i = 0.01
while True:
if round(R, ndigits=3) < 1 and round(B, ndigits=3) == 1:
R = R + i
G = G - i
elif round(G, ndigits=3) < 1:
G = G + i
B = B - i
elif round(B, ndigits=3) < 1:
B = B + i
R = R - i
vpython.rate(100)
orb.color = vpython.vector(R, G, B)

Chushruth
Автор

After a lot of thinking here is my version:


from vpython import *
red = 1
rSlope = 0
green = 1
gSlope = -0.01
blue = 0
bSlope = 0.01
mySphere = sphere(radius = 1, color = vector(red, green, blue))
while True:
rate(10)
red = red + rSlope
green = green + gSlope
blue = blue + bSlope
if (red <= 0):
rSlope = 0.01
bSlope = 0
gSlope = -0.01
if (green <= 0):
gSlope = 0.01
rSlope = 0
bSlope = -0.01
if (blue <= 0):
bSlope = 0.01
gSlope = 0
rSlope = -0.01
mySphere.color = vector(red, green, blue)

alonb
Автор

Thanks Paul! Looking forward to interfacing with Arduino.

leeg.
Автор

Why did we choose 1.5 as the limit for the channels?

aman-sood