How to flash mobject between two colors - manim

I want to define a Animation which change color of a mobject between two colors during specific time period.
E.g. a mobject with color RED, I want to set its color between RED and YELLOW back and forth 5 times during 2 seconds.
Below is my code (can change color, but the interval is not even), just want to confirm whether it is the correct way to do this, thanks!:
class ChangeColor(Animation):
def interpolate_submobject(self, submobject, starting_sumobject, alpha):
m = int(alpha * 10) % 2
if m == 0:
submobject.set_color(RED)
else:
submobject.set_color(YELLOW)

By default, alpha increment is smooth, so you have to change it to linear so that it is displayed correctly.
class ChangeColor(Animation):
CONFIG={
"rate_func":linear
}
def interpolate_submobject(self, submobject, starting_sumobject, alpha):
m = int(alpha * 10) % 2
if m == 0:
submobject.set_color(RED)
else:
submobject.set_color(YELLOW)

Related

How can I make these horizontal zigzags go in the vertical direction in the turtle python sandbox?

I got placed in a coding class and I have no idea what I'm doing.
This is supposed to create a nametag for a project that I have to finish by tonight.
Please help me figure out how to make the horizontal zigzags vertical.
t.pensize(24)
def zig_zag_line(num_zig_zags):
zig_zag = 0
t.setheading(20)
while zig_zag < num_zig_zags:
t.forward(40)
t.right(40)
t.forward(40)
t.left(40)
zig_zag = zig_zag + 1
def write_name(id_name):
style = ('Times New Roman', 70, 'bold')
t.write(id_name, font=style, align='center')
def white_space():
t.color("white")
t.pensize(26)
for i in range(3):
t.pu()
t.goto(-260, i * 30)
t.pd()
zig_zag_line(7)
i = i + 30
color1 = input("What is color 1?: ")
color2 = input("What is color 2?: ")
color3 = input("What is color 3?: ")
for i in range(-30, 33, 3):
if i % 9 == 0:
t.color(color1)
elif i % 9 == 3:
t.color(color2)
else:
t.color(color3)
t.pu()
t.goto(-260, i * 10)
t.pd()
zig_zag_line(7)
white_space()
t.color("black")
t.pu()
t.goto(0, 5)
t.pd()
write_name("")
t.hideturtle()
I just want to change the direction in which the zigzags are going. If anyone knows how to help I would really appreciate because I know virtually nothing about how to code this. I've been trying to figure it out but I'm going solely off the notes I've taken in class and I can't seem to figure out just how to make it go from horizontal to vertical.
There are two things we need to do: first swap our sense of x and y:
t.goto(-260, i * 10)
becomes:
t.goto(i * 10, -260)
and change our initial heading:
t.setheading(20)
becomes:
t.setheading(20 + 90)
A rework of the zigzag lines part of your code to make them vertical:
import turtle as t
def zig_zag_line(num_zig_zags):
t.setheading(110)
for _ in range(num_zig_zags):
t.forward(40)
t.right(40)
t.forward(40)
t.left(40)
color1 = input("What is color 1? ")
color2 = input("What is color 2? ")
color3 = input("What is color 3? ")
width, height = t.window_width(), t.window_height()
t.setup(height, width) # swap window wide and high
t.pensize(24)
t.speed('fastest') # because I have no patience
for i in range(-30, 33, 3):
if i % 9 == 0:
t.color(color1)
elif i % 9 == 3:
t.color(color2)
else:
t.color(color3)
t.penup()
t.goto(i * 10, -260)
t.pendown()
zig_zag_line(7)
t.hideturtle()
t.exitonclick()
I've included an optional third fix which is to swap the width and height of the window itself. Since the window might be sized to fit the horizontal drawing, we need to change it to fit the vertical drawing.

How to split the image into chunks without breaking character - python

I am trying to read image from the text.
I am getting better result if I break the images into small chunks but the problem is when i try to split the image it is cutting/slicing my characters.
code I am using :
from __future__ import division
import math
import os
from PIL import Image
def long_slice(image_path, out_name, outdir, slice_size):
"""slice an image into parts slice_size tall"""
img = Image.open(image_path)
width, height = img.size
upper = 0
left = 0
slices = int(math.ceil(height/slice_size))
count = 1
for slice in range(slices):
#if we are at the end, set the lower bound to be the bottom of the image
if count == slices:
lower = height
else:
lower = int(count * slice_size)
#set the bounding box! The important bit
bbox = (left, upper, width, lower)
working_slice = img.crop(bbox)
upper += slice_size
#save the slice
working_slice.save(os.path.join(outdir, "slice_" + out_name + "_" + str(count)+".png"))
count +=1
if __name__ == '__main__':
#slice_size is the max height of the slices in pixels
long_slice("/python_project/screenshot.png","longcat", os.getcwd(), 100)
Sample Image : The image i want to process
Expected/What i am trying to do :
I want to split every line as separate image without cutting the character
Line 1:
Line 2:
Current result:Characters in the image are cropped
I dont want to cut the image based on pixels since each document will have separate spacing and line width
Thanks
Jk
Here is a solution that finds the brightest rows in the image (i.e., the rows without text) and then splits the image on those rows. So far I have just marked the sections, and am leaving the actual cropping up to you.
The algorithm is as follows:
Find the sum of the luminance (I am just using the red channel) of every pixel in each row
Find the rows with sums that are at least 0.999 (which is the threshold I am using) as bright as the brightest row
Mark those rows
Here is the code that will return a list of these rows:
def find_lightest_rows(img, threshold):
line_luminances = [0] * img.height
for y in range(img.height):
for x in range(img.width):
line_luminances[y] += img.getpixel((x, y))[0]
line_luminances = [x for x in enumerate(line_luminances)]
line_luminances.sort(key=lambda x: -x[1])
lightest_row_luminance = line_luminances[0][1]
lightest_rows = []
for row, lum in line_luminances:
if(lum > lightest_row_luminance * threshold):
lightest_rows.add(row)
return lightest_rows
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 ... ]
After colouring these rows red, we have this image:

Algorithm to always sum sliders to 100% failing due to zeroes

This is (supposed to be) a function which makes sure that the the sum of a number of slider's values always adds up to globalTotal.
A slider value can be changed manually by the user to changer.value and then when applying this function to the values of the other sliders, it can determine their new or endVal.
It takes the startVal of the slider which needs changing and the original value of the slider that changed changerStartVal and can determine the new value others by weighting.
The problem and my question is. Sometimes remainingStartVals can be zero (when the slider changing gets moved all the way to maximum) or startVal can be zero (when the slider changing is moved to zero and then another slider is moved). When this happens I get a divide-by-zero or a multiply-by-zero respectively. Both of which are bad and lead to incorrect results. Is there an easy way to fix this?
func calcNewVal(startVal: Float, changerStartVal: Float) -> Float {
let remainingStartVals = globalTotal - changerStartVal
let remainingNewVals = globalTotal - changer.value
let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
return endVal
}
This is a mathematical problem, not a problem related to Swift or any specific programming language so I'll answer with mathematical formulas and explanations rather than code snippets.
I don't really understand your algorithm either. For example in this line:
let endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
you first multiply by 100 and then divide by 100, so you could just leave all these 100 factors out in the first place!
However, I think I understand what you're trying to achieve and the problem is that there is no generic solution. Before writing an algorithm you have to define exactly how you want it to behave, including all edge cases.
Let's define:
vi as the value of the i-th slider and
Δi as the change of the i-th slider's value
Then you have to think of the following cases:
Case 1:
0 < vi ≤ 1 for all sliders (other than the one you changed)
This is probably the common case you were thinking about. In this case you want to adjust the values of your unchanged sliders so that their total change is equal to the change Δchanged of the slider you changed. In other words:
∑i Δi = 0
If you have 3 sliders this reduces to:
Δ1 + Δ2 + Δ3 = 0
And if the slider that changed is the one with i = 1 then this requirement would read:
Δ1 = – (Δ2 + Δ3)
You want the sliders to adjust proportionally which means that this change Δ1 should not be distributed equally on the other sliders but depending on their current value:
Δ2 = – w2 * Δ1
Δ3 = – w3 * Δ1
The normed weight factors are
w2 = v2 / (v2 + v3)
w3 = v3 / (v2 + v3)
Thus we get:
Δ2 = – v2 / (v2 + v3) * Δ1
Δ3 = – v3 / (v2 + v3) * Δ1
So these are the formulas to applied for this particular case.
However, there are quite a few other cases that don't work with this approach:
Case 2:
vi = 0 for at least one, but not all of the sliders (other than the one you changed)
In this case the approach from case 1 would still work (plus it would be the logical thing to do). However, a slider's value would never change if it's zero. All of the change will be distributed over the sliders with a value > 0.
Case 3:
vi = 0 for all sliders (other than the one you changed)
In this case the proportional change doesn't work because there is simply no information how to distribute the change over the sliders. They're all zero! This is actually your zero division problem: In the case where we have 3 sliders and the slider 1 changes we'll get
v2 + v3 = 0
This is only another manifestation of the fact that the weight factors wi are simply undefined. Thus, you'll have to manually define what will happen in this case.
The most plausible thing to do in this case is to distribute the change evenly over all sliders:
Δi = – (1 / n) * Δ1
where n is the number of sliders (excluding the one that was changed!). With this logic, every slider gets "the same share" of the change.
Now that we're clear with our algorithm you can implement these cases in code. Here some pseudo code as an example:
if sum(valuesOfAllSlidersOtherThanTheSliderThatChanged) == 0 {
for allUnchangedSliders {
// distribute change evenly over the sliders
Δi = – (1 / n) * Δ_changedSlider
}
}
else {
for allUnchangedSliders {
// use weight factor to change proportionally
Δi = – v_i / ∑(v_i) * Δ_changedSlider
}
}
Please be aware that you must cache the values of the current state of your sliders at the beginning or (even better) first compute all the changes and then apply all the changes in a batch. Otherwise you will use a value v2' that you just computed for determining the value v3' which will obviously result in incorrect values.
Hey #Sean the simplest adjustment that I could think of here is to check if the remainingStartVals is not 0 that means that there are weights assigned to the other sliders and also check if a single slider had a weight to begin with which means its startVal shouldn't be equal to 0
func calcNewVal(startVal: Float, changerStartVal: Float) -> Float{
var endVal = 0
let remainingStartVals = globalTotal - changerStartVal
if remainingStartVals != 0 || startVal != 0{
let remainingNewVals = globalTotal - changer.value
endVal = ((startVal * (100 / remainingStartVals)) / 100) * remainingNewVals
}
return endVal
}

Spawn 3 objects but no duplicates in a row - Corona SDK

Im looking to spawn 3 objects (Red,Green,Blue) in seperate columns but should not duplicate. So somehow Im looking for it to check the colours in the other columns and place the one thats left over.
So if Blue and Red are already spawned, the last column will be a Green etc.
Should I need to specify specific orders inside a table and then everytime I spawn I just choose a random order from within that table, or is there a better way?
Cheers
You will always have to make sure you use the colour only once. How and when you do that is completely irrelevant.
Of course creating objects randomly is not very efficient as you would risk to create some you cannot use.
So best would be to create 3 different objects and remove one of them randomly every time or to spawn an object using a random colour, removed from a colour list.
You can create a list of colors and shuffle it. Something like that:
math.randomseed( os.time() )
local colors = {
{ 1,0,0 }, -- red
{ 0,1,0 }, -- green
{ 0,0,1 }, -- blue
}
local function shuffleTable( t )
local rand = math.random
assert( t, "shuffleTable() expected a table, got nil" )
local iterations = #t
local j
for i = iterations, 2, -1 do
j = rand(i)
t[i], t[j] = t[j], t[i]
end
end
shuffleTable( colors )
local px = display.contentCenterX
local py = display.contentCenterY - 200
for i = 1, #colors do
local rect = display.newRect( px, py + 100 * i, 200, 100 )
rect.fill = colors[i]
end

Gaussian filter in scipy

I want to apply a Gaussian filter of dimension 5x5 pixels on an image of 512x512 pixels. I found a scipy function to do that:
scipy.ndimage.filters.gaussian_filter(input, sigma, truncate=3.0)
How I choose the parameter of sigma to make sure that my Gaussian window is 5x5 pixels?
Check out the source code here: https://github.com/scipy/scipy/blob/master/scipy/ndimage/filters.py
You'll see that gaussian_filter calls gaussian_filter1d for each axis. In gaussian_filter1d, the width of the filter is determined implicitly by the values of sigma and truncate. In effect, the width w is
w = 2*int(truncate*sigma + 0.5) + 1
So
(w - 1)/2 = int(truncate*sigma + 0.5)
For w = 5, the left side is 2. The right side is 2 if
2 <= truncate*sigma + 0.5 < 3
or
1.5 <= truncate*sigma < 2.5
If you choose truncate = 3 (overriding the default of 4), you get
0.5 <= sigma < 0.83333...
We can check this by filtering an input that is all 0 except for a single 1 (i.e. find the impulse response of the filter) and counting the number of nonzero values in the filtered output. (In the following, np is numpy.)
First create an input with a single 1:
In [248]: x = np.zeros(9)
In [249]: x[4] = 1
Check the change in the size at sigma = 0.5...
In [250]: np.count_nonzero(gaussian_filter1d(x, 0.49, truncate=3))
Out[250]: 3
In [251]: np.count_nonzero(gaussian_filter1d(x, 0.5, truncate=3))
Out[251]: 5
... and at sigma = 0.8333...:
In [252]: np.count_nonzero(gaussian_filter1d(x, 0.8333, truncate=3))
Out[252]: 5
In [253]: np.count_nonzero(gaussian_filter1d(x, 0.8334, truncate=3))
Out[253]: 7
Following the excellent previous answer:
set sigma s = 2
set window size w = 5
evaluate the 'truncate' value: t = (((w - 1)/2)-0.5)/s
filtering: filtered_data = scipy.ndimage.filters.gaussian_filter(data, sigma=s, truncate=t)

Resources