How to create an animation using celluloid library? - python

There I created an animation using celluloid library. This animation shows the point which move along the elliptical line. The problem is that, when I run this code, everything is working in sublime text, but when I use Jupyter, it outputs error. How can I solve this problem? You can see my code in the answers.
import math
import numpy as np
import matplotlib.pyplot as plt
from celluloid import Camera
import copy
img = np.ones((90,60,3))
fig = plt.figure(figsize=(10,8), dpi = 100, facecolor='w')
camera = Camera(fig)
quarterCircleOne = []
quarterCircleTwoHalfOne = []
quarterCircleTwoHalfTwo = []
quarterCircleThree = []
quarterCircleFourHalfOne = []
quarterCircleFourHalfTwo = []
xc = 45
yc = 30
rx = 25
ry = 15
def GenerateElipse(xc,yc,rx,ry):
img[xc, yc] = (255,0,0)
img[xc+1, yc] = (255,0,0)
img[xc-1, yc] = (255,0,0)
img[xc, yc+1] = (255,0,0)
img[xc, yc-1] = (255,0,0)
xk = 0
yk = ry
pk = ry**2 -rx**2 * ry+1/4* rx**2
while ry**2 * xk < rx**2 *yk:
if pk>0:
xk = xk+1
yk = yk-1
pk = pk + 2 * ry**2 *xk + ry**2 - 2* rx**2 *yk
else:
xk = xk+1
pk=pk + 2* ry**2 * xk + ry**2
img[xc+xk, yc+yk] = (0,0,0)
img[xc+xk, yc-yk] = (0,0,0)
img[xc-xk, yc+yk] = (0,0,0)
img[xc-xk, yc-yk] = (0,0,0)
quarterCircleOne.append([xc-xk, yc-yk])
quarterCircleTwoHalfTwo.append([xc-xk, yc+yk])
quarterCircleThree.append([xc+xk, yc+yk])
quarterCircleFourHalfOne.append([xc+xk, yc-yk])
pk = ry**2 * (xk-1/2)**2 + rx**2 * (yk-1)**2 - rx**2 * ry**2
while yk>0:
if pk>0:
yk = yk-1
pk=pk -2 * rx**2 * yk + rx**2
else:
xk = xk+1
yk = yk-1
pk=pk - 2 * rx**2 * yk + 2* ry**2 *xk + rx**2
img[xc+xk, yc+yk] = (0,0,0)
img[xc+xk, yc-yk] = (0,0,0)
img[xc-xk, yc+yk] = (0,0,0)
img[xc-xk, yc-yk] = (0,0,0)
quarterCircleOne.append([xc-xk, yc-yk])
quarterCircleTwoHalfOne.append([xc-xk, yc+yk])
quarterCircleThree.append([xc+xk, yc+yk])
quarterCircleFourHalfTwo.append([xc+xk, yc-yk])
GenerateElipse(45, 30, 25, 15)
def DrawElipse(speed, img):
sortedQuarterCircleOne = sorted(quarterCircleOne,key=lambda x: x[1])
sortedQuarterCircleTwoHalfOne =
sorted(quarterCircleTwoHalfOne,key=lambda x: x[1])
sortedQuarterCircleTwoHalfTwo =
sorted(quarterCircleTwoHalfTwo,key=lambda x: x[0])
sortedQuarterCircleThree = sorted(quarterCircleThree,key=lambda x: x[1],
reverse=True)
sortedQuarterCircleFourHalfTwo =
sorted(quarterCircleFourHalfTwo,key=lambda x: x[1], reverse=True)
sortedQuarterCircleFourHalfOne =
sorted(quarterCircleFourHalfOne,key=lambda x: x[0], reverse=True)
circle = [sortedQuarterCircleOne, sortedQuarterCircleTwoHalfOne,
sortedQuarterCircleTwoHalfTwo, sortedQuarterCircleThree,
sortedQuarterCircleFourHalfTwo, sortedQuarterCircleFourHalfOne]
i = 0
for x in range(0, 6):
for coordinates in circle[x]:
freshImage = copy.deepcopy(img)
freshImage[coordinates[0], coordinates[1]] = (0,0,0)
freshImage[coordinates[0], coordinates[1]+1] = (255,0,0)
freshImage[coordinates[0], coordinates[1]-1] = (255,0,0)
freshImage[coordinates[0]+1, coordinates[1]-1] = (0,0,255)
freshImage[coordinates[0]+1, coordinates[1]+1] = (0,0,255)
freshImage[coordinates[0]+1, coordinates[1]] = (255,0,0)
freshImage[coordinates[0]-1, coordinates[1]-1] = (0,0,255)
freshImage[coordinates[0]-1, coordinates[1]+1] = (0,0,255)
freshImage[coordinates[0]-1, coordinates[1]] = (255,0,0)
if i % speed == 0:
plt.imshow(freshImage)
camera.snap()
i = i + 1
DrawElipse(1, img);
animation = camera.animate()
plt.show()

The "error" Clipping input data to the valid range... stems from the data you give to plt.imshow. It hints that you should supply data within [0..255] for integers e.g. np.uint8 and [0..1] for floating point types e.g. np.float32. Check your input data, and clip it beforehand if necessary, or cast it to the right datatype, e.g. plt.imshow(np.uint8(freshImage)).
That error is not what makes the animation not show up; it's an error provided by matplotlib's imshow. It will actually do its best to render the image despite the problem in the input range.
To see the animation use this in the end (in a Jupyter notebook, remember to from IPython.display import HTML):
animation = camera.animate()
HTML(animation.to_html5_video())
As per the documentation for Celluliod: https://github.com/jwkvam/celluloid

Related

How to display tkinter polygons on canvas under 3D conditions?

I'm trying to create a program that renders an object in 3D and that you can rotate and control with your mouse's position. I'm trying to display the faces of the object but I don't know how could I display the closer faces first so that there isn't any 'background' face displayed in front of closer faces.
the code I provided is fully reproducable, just copy and paste it if you have tkinter and numpy.
from numpy import *
from tkinter import *
#eulers angles matrixes
def Rx(theta):
return mat(mat([[1, 0 , 0 ],
[0, cos(theta), -sin(theta)],
[0, sin(theta), cos(theta) ]]).round(15))
def Ry(theta):
return mat(mat([[cos(theta), 0, -sin(theta)],
[ 0 , 1, 0 ],
[sin(theta), 0, cos(theta) ]]).round(15))
def Rz(theta):
return mat(mat([[cos(theta), -sin(theta), 0],
[sin(theta), cos(theta) , 0],
[ 0 , 0 , 1]]).round(15))
#returns a 2d projection matrix,
def proj2d(p):
return mat(eye(2,3)*p)
#tuple into vector
def vector(tuple):
return transpose(mat(list(tuple)))
#updates position of the 3D point in function of the x,y,z angles
def position(pts3d,anglex,angley,anglez):
for i in range(len(pts3d)):
pts3d[i] = (float((Rx(anglex) * vector(pts3d[i]))[0]),
float((Rx(anglex) * vector(pts3d[i]))[1]),
float((Rx(anglex) * vector(pts3d[i]))[2]))
pts3d[i] = (float((Ry(angley) * vector(pts3d[i]))[0]),
float((Ry(angley) * vector(pts3d[i]))[1]),
float((Ry(angley) * vector(pts3d[i]))[2]))
pts3d[i] = (float((Rz(anglez) * vector(pts3d[i]))[0]),
float((Rz(anglez) * vector(pts3d[i]))[1]),
float((Rz(anglez) * vector(pts3d[i]))[2]))
#makes a projection of the 3d points on the 2d screen
def projected(pts3d):
pts2d = []
for i in pts3d:
pts2d.append((float((proj2d(30+0.75*i[2]) * vector(i))[0]),
float((proj2d(30+0.75*i[2]) * vector(i))[1])))
return pts2d
#displays dots
def dots(canvas,points):
for i in points:
canvas.create_oval(H/2+5+i[0],H/2+5+i[1],H/2-5+i[0],H/2-5+i[1],fill = 'white')
#displays vertices
def connect(canvas,vertics,points):
for i in vertics:
canvas.create_line(H/2+points[int(i[0])][0],H/2+points[int(i[0])][1],H/2+points[int(i[1])][0],H/2+points[int(i[1])][1],width = 2,fill = 'white')
#what I should modify, I guess: it's the funtion that displays the faces of the object
def face(canvas,faces,points,colors):
for i in range(len(faces)):
coordsface = ()
for j in faces[i]:
coordsface += (H/2+points[int(j)][0],H/2+points[int(j)][1])
canvas.create_polygon(coordsface,fill = colors[i])
#major functions, updates position each time interval(delay)
def updateposition(self,H,canvas,points,vertics,faces,clrfc,delai,domegax,domegay,domegaz):
canvas.delete('all')
y,x = self.winfo_pointerx() - self.winfo_rootx() - H/2, self.winfo_pointery() - self.winfo_rooty() - H/2
if abs(x) >= H/2 or abs(y) >= H/2: x,y = 0,0
domegax -= 0.00001*(x)
domegay -= 0.00001*(y)
position(points,domegax,domegay,domegaz)
if affpts == 'y':
dots(canvas,projected(points))
if affart == 'y':
connect(canvas,vertics,projected(points))
if afffac == 'y':
face(canvas,faces,projected(points),clrfc)
self.after(delai,updateposition,self,H,canvas,points,vertics,faces,clrfc,delai,domegax,domegay,domegaz)
## cube
def pts3Dcube():
#points
a = ( L/2, L/2, L/2)
b = ( L/2, L/2,-L/2)
c = ( L/2,-L/2, L/2)
d = ( L/2,-L/2,-L/2)
e = (-L/2, L/2, L/2)
f = (-L/2, L/2,-L/2)
g = (-L/2,-L/2, L/2)
h = (-L/2,-L/2,-L/2)
pts3d = [a,b,c,d,e,f,g,h]
#vertices
aretes = []
for i in [0,2,4,6]:
aretes.append(str(i)+str(i+1))
for i in [0,1,4,5]:
aretes.append(str(i)+str(i+2))
for i in [0,1,2,3]:
aretes.append(str(i)+str(i+4))
#faces
faces = ['0132','4576','0154','2376','1375','0264']
clrfc = ['green','red','yellow','blue','orange','white']
return pts3d, aretes, faces, clrfc
## initial conditions
L = 5
H = 600
delai = 5
self = Tk()
canvas = Canvas(self,height = H,width = H,bg = 'gray13')
canvas.pack()
objet = pts3Dcube() #object choice
domegax = 0.0
domegay = 0.0
domegaz = 0.0
#initial rotation angles
iomegax = 0
iomegay = 0
iomegaz = 0
#displaying points, vertices, faces or not
affpts = 'y'
affart = 'y'
afffac = 'y'
position(objet[0],iomegax,iomegay,iomegaz) #initial rotation
updateposition(self,H,canvas,objet[0],objet[1],objet[2],objet[3],delai,domegax,domegay,domegaz) # dynamic rotation
if any of you have an idea, please comment it or something, I'm lost.
Thanks!

cannot run the sklearn machine learning model

I am trying to use the sklearn to build a machine learning model for the lunar lander. I use Grid search to tune the model and use joblib to persist the model.
enter image description here
here is the code:
from sklearn.externals import joblib
joblib.dump(my_tuned_model, 'player_state.pkl')
and then I copy the player_state.pkl into the folder of lunar lander. below is the code of lunar_lander
import sys, math
import numpy as np
from sklearn.externals import joblib
import cv2
# MOD Extra imports for image handling
from PIL import Image
import os
import time
import datetime
import keras
import Box2D
from Box2D.b2 import (edgeShape, circleShape, fixtureDef, polygonShape, revoluteJointDef, contactListener)
import gym
from gym import spaces
from gym.utils import seeding
# Rocket trajectory optimization is a classic topic in Optimal Control.
#
# According to Pontryagin's maximum principle it's optimal to fire engine full throttle or
# turn it off. That's the reason this environment is OK to have discreet actions (engine on or off).
#
# Landing pad is always at coordinates (0,0). Coordinates are the first two numbers in state vector.
# Reward for moving from the top of the screen to landing pad and zero speed is about 100..140 points.
# If lander moves away from landing pad it loses reward back. Episode finishes if the lander crashes or
# comes to rest, receiving additional -100 or +100 points. Each leg ground contact is +10. Firing main
# engine is -0.3 points each frame. Solved is 200 points.
#
# Landing outside landing pad is possible. Fuel is infinite, so an agent can learn to fly and then land
# on its first attempt. Please see source code for details.
#
# Too see heuristic landing, run:
#
# python gym/envs/box2d/lunar_lander_mod.py
#
# To play yourself, run:
#
# python examples/agents/keyboard_agent.py LunarLander-v0
#
# Created by Oleg Klimov. Licensed on the same terms as the rest of OpenAI Gym.
FPS = 50
SCALE = 30.0 # affects how fast-paced the game is, forces should be adjusted as well
MAIN_ENGINE_POWER = 13.0
SIDE_ENGINE_POWER = 0.6
INITIAL_RANDOM = 1000.0 # Set 1500 to make game harder
LANDER_POLY = [
(-14, +17), (-17, 0), (-17, -10),
(+17, -10), (+17, 0), (+14, +17)
]
LEG_AWAY = 20
LEG_DOWN = 18
LEG_W, LEG_H = 2, 8
LEG_SPRING_TORQUE = 40
SIDE_ENGINE_HEIGHT = 14.0
SIDE_ENGINE_AWAY = 12.0
VIEWPORT_W = 600
VIEWPORT_H = 400
class ContactDetector(contactListener):
def __init__(self, env):
contactListener.__init__(self)
self.env = env
def BeginContact(self, contact):
if self.env.lander == contact.fixtureA.body or self.env.lander == contact.fixtureB.body:
self.env.game_over = True
for i in range(2):
if self.env.legs[i] in [contact.fixtureA.body, contact.fixtureB.body]:
self.env.legs[i].ground_contact = True
def EndContact(self, contact):
for i in range(2):
if self.env.legs[i] in [contact.fixtureA.body, contact.fixtureB.body]:
self.env.legs[i].ground_contact = False
class LunarLander(gym.Env):
metadata = {
'render.modes': ['human', 'rgb_array'],
'video.frames_per_second': FPS
}
continuous = False
def __init__(self):
self.seed()
self.viewer = None
self.world = Box2D.b2World()
self.moon = None
self.lander = None
self.particles = []
self.prev_reward = None
high = np.array([np.inf] * 8) # useful range is -1 .. +1, but spikes can be higher
self.observation_space = spaces.Box(-high, high)
if self.continuous:
# Action is two floats [main engine, left-right engines].
# Main engine: -1..0 off, 0..+1 throttle from 50% to 100% power. Engine can't work with less than 50% power.
# Left-right: -1.0..-0.5 fire left engine, +0.5..+1.0 fire right engine, -0.5..0.5 off
self.action_space = spaces.Box(-1, +1, (2,))
else:
# Nop, fire left engine, main engine, right engine
self.action_space = spaces.Discrete(4)
self.reset()
def seed(self, seed=None):
self.np_random, seed = seeding.np_random(seed)
return [seed]
def _destroy(self):
if not self.moon: return
self.world.contactListener = None
self._clean_particles(True)
self.world.DestroyBody(self.moon)
self.moon = None
self.world.DestroyBody(self.lander)
self.lander = None
self.world.DestroyBody(self.legs[0])
self.world.DestroyBody(self.legs[1])
def reset(self):
self._destroy()
self.world.contactListener_keepref = ContactDetector(self)
self.world.contactListener = self.world.contactListener_keepref
self.game_over = False
self.prev_shaping = None
W = VIEWPORT_W / SCALE
H = VIEWPORT_H / SCALE
# terrain
CHUNKS = 11
height = self.np_random.uniform(0, H / 2, size=(CHUNKS + 1,))
chunk_x = [W / (CHUNKS - 1) * i for i in range(CHUNKS)]
self.helipad_x1 = chunk_x[CHUNKS // 2 - 1]
self.helipad_x2 = chunk_x[CHUNKS // 2 + 1]
self.helipad_y = H / 4
height[CHUNKS // 2 - 2] = self.helipad_y
height[CHUNKS // 2 - 1] = self.helipad_y
height[CHUNKS // 2 + 0] = self.helipad_y
height[CHUNKS // 2 + 1] = self.helipad_y
height[CHUNKS // 2 + 2] = self.helipad_y
smooth_y = [0.33 * (height[i - 1] + height[i + 0] + height[i + 1]) for i in range(CHUNKS)]
self.moon = self.world.CreateStaticBody(shapes=edgeShape(vertices=[(0, 0), (W, 0)]))
self.sky_polys = []
for i in range(CHUNKS - 1):
p1 = (chunk_x[i], smooth_y[i])
p2 = (chunk_x[i + 1], smooth_y[i + 1])
self.moon.CreateEdgeFixture(
vertices=[p1, p2],
density=0,
friction=0.1)
self.sky_polys.append([p1, p2, (p2[0], H), (p1[0], H)])
self.moon.color1 = (0.0, 0.0, 0.0)
self.moon.color2 = (0.0, 0.0, 0.0)
initial_y = VIEWPORT_H / SCALE
self.lander = self.world.CreateDynamicBody(
position=(VIEWPORT_W / SCALE / 2, initial_y),
angle=0.0,
fixtures=fixtureDef(
shape=polygonShape(vertices=[(x / SCALE, y / SCALE) for x, y in LANDER_POLY]),
density=5.0,
friction=0.1,
categoryBits=0x0010,
maskBits=0x001, # collide only with ground
restitution=0.0) # 0.99 bouncy
)
self.lander.color1 = (0.5, 0.4, 0.9)
self.lander.color2 = (0.3, 0.3, 0.5)
self.lander.ApplyForceToCenter((
self.np_random.uniform(-INITIAL_RANDOM, INITIAL_RANDOM),
self.np_random.uniform(-INITIAL_RANDOM, INITIAL_RANDOM)
), True)
self.legs = []
for i in [-1, +1]:
leg = self.world.CreateDynamicBody(
position=(VIEWPORT_W / SCALE / 2 - i * LEG_AWAY / SCALE, initial_y),
angle=(i * 0.05),
fixtures=fixtureDef(
shape=polygonShape(box=(LEG_W / SCALE, LEG_H / SCALE)),
density=1.0,
restitution=0.0,
categoryBits=0x0020,
maskBits=0x001)
)
leg.ground_contact = False
leg.color1 = (0.5, 0.4, 0.9)
leg.color2 = (0.3, 0.3, 0.5)
rjd = revoluteJointDef(
bodyA=self.lander,
bodyB=leg,
localAnchorA=(0, 0),
localAnchorB=(i * LEG_AWAY / SCALE, LEG_DOWN / SCALE),
enableMotor=True,
enableLimit=True,
maxMotorTorque=LEG_SPRING_TORQUE,
motorSpeed=+0.3 * i # low enough not to jump back into the sky
)
if i == -1:
rjd.lowerAngle = +0.9 - 0.5 # Yes, the most esoteric numbers here, angles legs have freedom to travel within
rjd.upperAngle = +0.9
else:
rjd.lowerAngle = -0.9
rjd.upperAngle = -0.9 + 0.5
leg.joint = self.world.CreateJoint(rjd)
self.legs.append(leg)
self.drawlist = [self.lander] + self.legs
return self.step(np.array([0, 0]) if self.continuous else 0)[0]
def _create_particle(self, mass, x, y, ttl):
p = self.world.CreateDynamicBody(
position=(x, y),
angle=0.0,
fixtures=fixtureDef(
shape=circleShape(radius=2 / SCALE, pos=(0, 0)),
density=mass,
friction=0.1,
categoryBits=0x0100,
maskBits=0x001, # collide only with ground
restitution=0.3)
)
p.ttl = ttl
self.particles.append(p)
self._clean_particles(False)
return p
def _clean_particles(self, all):
while self.particles and (all or self.particles[0].ttl < 0):
self.world.DestroyBody(self.particles.pop(0))
def step(self, action):
assert self.action_space.contains(action), "%r (%s) invalid " % (action, type(action))
# Engines
tip = (math.sin(self.lander.angle), math.cos(self.lander.angle))
side = (-tip[1], tip[0]);
dispersion = [self.np_random.uniform(-1.0, +1.0) / SCALE for _ in range(2)]
m_power = 0.0
if (self.continuous and action[0] > 0.0) or (not self.continuous and action == 2):
# Main engine
if self.continuous:
m_power = (np.clip(action[0], 0.0, 1.0) + 1.0) * 0.5 # 0.5..1.0
assert m_power >= 0.5 and m_power <= 1.0
else:
m_power = 1.0
ox = tip[0] * (4 / SCALE + 2 * dispersion[0]) + side[0] * dispersion[
1] # 4 is move a bit downwards, +-2 for randomness
oy = -tip[1] * (4 / SCALE + 2 * dispersion[0]) - side[1] * dispersion[1]
impulse_pos = (self.lander.position[0] + ox, self.lander.position[1] + oy)
p = self._create_particle(3.5, impulse_pos[0], impulse_pos[1],
m_power) # particles are just a decoration, 3.5 is here to make particle speed adequate
p.ApplyLinearImpulse((ox * MAIN_ENGINE_POWER * m_power, oy * MAIN_ENGINE_POWER * m_power), impulse_pos,
True)
self.lander.ApplyLinearImpulse((-ox * MAIN_ENGINE_POWER * m_power, -oy * MAIN_ENGINE_POWER * m_power),
impulse_pos, True)
s_power = 0.0
if (self.continuous and np.abs(action[1]) > 0.5) or (not self.continuous and action in [1, 3]):
# Orientation engines
if self.continuous:
direction = np.sign(action[1])
s_power = np.clip(np.abs(action[1]), 0.5, 1.0)
assert s_power >= 0.5 and s_power <= 1.0
else:
direction = action - 2
s_power = 1.0
ox = tip[0] * dispersion[0] + side[0] * (3 * dispersion[1] + direction * SIDE_ENGINE_AWAY / SCALE)
oy = -tip[1] * dispersion[0] - side[1] * (3 * dispersion[1] + direction * SIDE_ENGINE_AWAY / SCALE)
impulse_pos = (self.lander.position[0] + ox - tip[0] * 17 / SCALE,
self.lander.position[1] + oy + tip[1] * SIDE_ENGINE_HEIGHT / SCALE)
p = self._create_particle(0.7, impulse_pos[0], impulse_pos[1], s_power)
p.ApplyLinearImpulse((ox * SIDE_ENGINE_POWER * s_power, oy * SIDE_ENGINE_POWER * s_power), impulse_pos,
True)
self.lander.ApplyLinearImpulse((-ox * SIDE_ENGINE_POWER * s_power, -oy * SIDE_ENGINE_POWER * s_power),
impulse_pos, True)
self.world.Step(1.0 / FPS, 6 * 30, 2 * 30)
pos = self.lander.position
vel = self.lander.linearVelocity
state = [
(pos.x - VIEWPORT_W / SCALE / 2) / (VIEWPORT_W / SCALE / 2),
(pos.y - (self.helipad_y + LEG_DOWN / SCALE)) / (VIEWPORT_W / SCALE / 2),
vel.x * (VIEWPORT_W / SCALE / 2) / FPS,
vel.y * (VIEWPORT_H / SCALE / 2) / FPS,
self.lander.angle,
20.0 * self.lander.angularVelocity / FPS,
1.0 if self.legs[0].ground_contact else 0.0,
1.0 if self.legs[1].ground_contact else 0.0
]
assert len(state) == 8
reward = 0
shaping = \
- 100 * np.sqrt(state[0] * state[0] + state[1] * state[1]) \
- 100 * np.sqrt(state[2] * state[2] + state[3] * state[3]) \
- 100 * abs(state[4]) + 10 * state[6] + 10 * state[7] # And ten points for legs contact, the idea is if you
# lose contact again after landing, you get negative reward
if self.prev_shaping is not None:
reward = shaping - self.prev_shaping
self.prev_shaping = shaping
reward -= m_power * 0.30 # less fuel spent is better, about -30 for heurisic landing
reward -= s_power * 0.03
done = False
if self.game_over or abs(state[0]) >= 1.0:
done = True
reward = -100
if not self.lander.awake:
done = True
reward = +100
return np.array(state), reward, done, {}
def render(self, mode='human'):
from gym.envs.classic_control import rendering
if self.viewer is None:
self.viewer = rendering.Viewer(VIEWPORT_W, VIEWPORT_H)
self.viewer.set_bounds(0, VIEWPORT_W / SCALE, 0, VIEWPORT_H / SCALE)
for obj in self.particles:
obj.ttl -= 0.15
obj.color1 = (max(0.2, 0.2 + obj.ttl), max(0.2, 0.5 * obj.ttl), max(0.2, 0.5 * obj.ttl))
obj.color2 = (max(0.2, 0.2 + obj.ttl), max(0.2, 0.5 * obj.ttl), max(0.2, 0.5 * obj.ttl))
self._clean_particles(False)
for p in self.sky_polys:
self.viewer.draw_polygon(p, color=(0, 0, 0))
for obj in self.particles + self.drawlist:
for f in obj.fixtures:
trans = f.body.transform
if type(f.shape) is circleShape:
t = rendering.Transform(translation=trans * f.shape.pos)
self.viewer.draw_circle(f.shape.radius, 20, color=obj.color1).add_attr(t)
self.viewer.draw_circle(f.shape.radius, 20, color=obj.color2, filled=False, linewidth=2).add_attr(t)
else:
path = [trans * v for v in f.shape.vertices]
self.viewer.draw_polygon(path, color=obj.color1)
path.append(path[0])
self.viewer.draw_polyline(path, color=obj.color2, linewidth=2)
for x in [self.helipad_x1, self.helipad_x2]:
flagy1 = self.helipad_y
flagy2 = flagy1 + 50 / SCALE
self.viewer.draw_polyline([(x, flagy1), (x, flagy2)], color=(1, 1, 1))
self.viewer.draw_polygon([(x, flagy2), (x, flagy2 - 10 / SCALE), (x + 25 / SCALE, flagy2 - 5 / SCALE)],
color=(0.8, 0.8, 0))
return self.viewer.render(return_rgb_array=mode == 'rgb_array')
def close(self):
if self.viewer is not None:
self.viewer.close()
self.viewer = None
class LunarLanderContinuous(LunarLander):
continuous = True
if __name__ == "__main__":
# Load the Lunar Lander environment
env = LunarLander()
total_rewards = list()
for i in range(0, 10):
s = env.reset()
# Load and initialise the contrll model
ROWS = 64
COLS = 64
CHANNELS = 1
model = joblib.load('player_state.pkl')
# Run the game loop
total_reward = 0
steps = 0
while True:
# Get the model to make a prediction
a = model.predict_classes(s)
a = a[0]
# Step on the game
s, r, done, info = env.step(a)
env.render()
total_reward += r
if steps % 20 == 0 or done:
print(["{:+0.2f}".format(x) for x in s])
print("step {} total_reward {:+0.2f}".format(steps, total_reward))
steps += 1
if done:
total_rewards.append(total_reward)
break
print("total rewards", total_rewards)
print("average total reward", np.mean(total_rewards))
# Write total rewards to file
f = open("lunarlander_ml_states_rewards.csv", 'w')
wr = csv.writer(f)
for r in total_rewards:
wr.writerow([r, ])
f.close()
When I run the code, an error occurs
Traceback (most recent call last):
File "/Users/leejoonsung/PycharmProjects/lunar_lander/lunar_lander_ml_states_player.py", line 406, in <module>
a = model.predict_classes(s)
AttributeError: 'GridSearchCV' object has no attribute 'predict_classes'
Could anyone help me solve the problem

Weird ordering of bytes from one pixel to the next in simple PIL bitmap. What is likely wrong?

Here is the code.
import os
import io
import PIL
#import pyximport; pyximport.install()
#from pixel_tools import PixelsBMP
from PIL import Image, ImageGrab
# TODO convert to Cython
class PixelsBMP:
def __init__(self, img):
if isinstance(img, str):
img = Image.open(img)
with io.BytesIO() as bytes_io:
img.save(bytes_io, 'BMP')
data = bytes_io.getvalue()
offset = int.from_bytes(data[10:14], byteorder='little', signed=False)
data = data[offset:] # pixels start here
self.data = data
self.width = img.width
self.height = img.height
self.bands = 3 if img.mode == 'RGB' else 4
def debugPrintPixels(self):
import sys
d = self.data
print('width:', self.width)
print('height:', self.height)
print('bands (alpha=>4):', self.bands)
for y in range(0, self.height):
for x in range(0, self.width):
offs = self.width * self.bands * y + x
sys.stdout.write('(' + str(d[offs]) + ',' + str(d[offs + 1]) + ',' + str(d[offs + 2]) + ((',' + str(d[offs + 3])) if self.bands == 4 else '') + ')')
print()
if __name__ == '__main__':
subpx = PixelsBMP('images/PixelsBMP_test_subImage.png')
subpx.debugPrintPixels()
##pixels = PixelsBMP('images/PixelsBMP_test_superImage.png')
##point = pixels.exactSubpixelSearch(subpx)
#print(point)
print('test done')
What it prints is:
width: 7
height: 3
bands (alpha=>4): 4
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
(100,50,25,255)(50,25,255,100)(25,255,100,50)(255,100,50,25)(100,50,25,255)(50,25,255,100)(25,255,100,50)
None
test done
For this 7x3 navy blue bitmap. Pixels are: (25, 50, 100) solid RGB.
(It's small, right after this line):
So, the BGR ordering isn't shocking or significant here, but the fact that the order changes from the first pixel to the second:
(100,50,25,255)(50,25,255,100).
I'm lazy tonight. What am I doing wrong?
Found the issue:
offs = self.width * self.bands * y + x
in the debugPrint routine should be:
offs = self.width * self.bands * y + x * self.bands
as clearly each pixel is bands wide.
Output of the printer is correct now.

spiraling hexagonal grid in python

I want to create a hexagonal grid using XYZ coordinates that is constructed in a spiraling pattern. This is my current code, which produces a grid depicted by the red arrows below. My problem area is circled. Rather than going from [-1,0,1] to [0,-2,2] I need to move from [-1,0,1] to [-1,-1,2] (following the blue line).
The complete code appears below the hash line- I am creating the visualization in Blender 2.65a
radius = 11 # determines size of field
deltas = [[1,0,-1],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0]]
hex_coords = []
for r in range(radius):
x = 0
y = -r
z = +r
points = x,y,z
hex_coords.append(points)
for j in range(6):
if j==5:
num_of_hexas_in_edge = r-1
else:
num_of_hexas_in_edge = r
for i in range(num_of_hexas_in_edge):
x = x+deltas[j][0]
y = y+deltas[j][1]
z = z+deltas[j][2]
plot = x,y,z
hex_coords.append(plot)
-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-
import bpy
FOXP2 = '''
CTTGAACCTTTGTCACCCCTCACGTTGCACACCAAAGACATACCCTAGTGATTAAATGCTGATTTTGTGT
ACGATTGTCCACGGACGCCAAAACAATCACAGAGCTGCTTGATTTGTTTTAATTACCAGCACAAAATGCC
CAATTCCTCCTCGACTACCTCCTCCAACACTTCCAAAGCATCACCACCAATAACTCATCATTCCATAGTG
AATGGACAGTCTTCAGTTCTAAGTGCAAGACGAGACAGCTCGTCACATGAGGAGACTGGGGCCTCTCACA
CTCTCTATGGCCATGGAGTTTGCAAATGGCCAGGCTGTGAAAGCATTTGTGAAGATTTTGGACAGTTTTT
AAAGCACCTTAACAATGAACACGCATTGGATGACCGAAGCACTGCTCAGTGTCGAGTGCAAATGCAGGTG
GTGCAACAGTTAGAAATACAGCTTTCTAAAGAACGCGAACGTCTTCAAGCAATGATGACCCACTTGCACA
'''
set_size = len(FOXP2)
def makeMaterial(name, diffuse, specular, alpha):
mat = bpy.data.materials.new(name)
mat.diffuse_color = diffuse
mat.diffuse_shader = 'LAMBERT'
mat.diffuse_intensity = 1.0
mat.specular_color = specular
mat.specular_shader = 'COOKTORR'
mat.specular_intensity = 0.5
mat.alpha = alpha
mat.ambient = 1
return mat
def setMaterial(ob, mat):
me = ob.data
me.materials.append(mat)
# Create four materials
red = makeMaterial('Red', (1,0,0), (0,0,0), .5)
blue = makeMaterial('BlueSemi', (0,0,1), (0,0,0), 0.5)
green = makeMaterial('Green',(0,1,0), (0,0,0), 0.5)
yellow = makeMaterial('Yellow',(1,1,0), (0,0,0), 0.5)
black = makeMaterial('Black',(0,0,0), (0,0,0), 0.5)
white = makeMaterial('White',(1,1,1), (0,0,0), 0.5)
def make_sphere(volume, position):
create = bpy.ops.mesh.primitive_uv_sphere_add
create(size=volume, location=position)
# Builds a list of coordinate points
radius = 11
deltas = [[1,0,-1],[0,1,-1],[-1,1,0],[-1,0,1],[0,-1,1],[1,-1,0]]
hex_coords = []
for r in range(radius):
x = 0
y = -r
z = +r
points = x,y,z
hex_coords.append(points)
for j in range(6):
if j==5:
num_of_hexas_in_edge = r-1
else:
num_of_hexas_in_edge = r
for i in range(num_of_hexas_in_edge):
x = x+deltas[j][0]
y = y+deltas[j][1]
z = z+deltas[j][2]
plot = x,y,z
hex_coords.append(plot)
# Color-codes sequence and appends to color_array
color_array = []
for x in FOXP2:
if x == 'A':
color_array.append(1)
elif x == 'T':
color_array.append(1)
elif x == 'C':
color_array.append(0)
elif x == 'G':
color_array.append(0)
else:
pass
# Pulls from sequence data and applies color to sphere
# Positions sphere to coordinates
# Pulls from color_code and applies color scheme to sphere object
for x in color_array:
if x =='RED':
coord_tuple = hex_coords.pop(0)
make_sphere(1, coord_tuple)
setMaterial(bpy.context.object, red)
elif x =='GREEN':
coord_tuple = hex_coords.pop(0)
make_sphere(1, coord_tuple)
setMaterial(bpy.context.object, green)
elif x =='BLUE':
coord_tuple = hex_coords.pop(0)
make_sphere(1, coord_tuple)
setMaterial(bpy.context.object, blue)
elif x =='YELLOW':
coord_tuple = hex_coords.pop(0)
make_sphere(1, coord_tuple)
setMaterial(bpy.context.object, yellow)
else:
pass

Creating a tiled map with blender

I'm looking at creating map tiles based on a 3D model made in blender,
The map is 16 x 16 in blender.
I've got 4 different zoom levels and each tile is 100 x 100 pixels. The entire map at the most zoomed out level is 4 x 4 tiles constructing an image of 400 x 400.
The most zoomed in level is 256 x 256 obviously constructing an image of 25600 x 25600
What I need is a script for blender that can create the tiles from the model.
I've never written in python before so I've been trying to adapt a couple of the scripts which are already there.
So far I've come up with a script, but it doesn't work very well. I'm having real difficulties getting the tiles to line up seamlessly. I'm not too concerned about changing the height of the camera as I can always create the same zoomed out tiles at 6400 x 6400 images and split the resulting images into the correct tiles.
Here is what I've got so far...
#!BPY
"""
Name: 'Export Map Tiles'
Blender: '242'
Group: 'Export'
Tip: 'Export to Map'
"""
import Blender
from Blender import Scene,sys
from Blender.Scene import Render
def init():
thumbsize = 200
CameraHeight = 4.4
YStart = -8
YMove = 4
XStart = -8
XMove = 4
ZoomLevel = 1
Path = "/Images/Map/"
Blender.drawmap = [thumbsize,CameraHeight,YStart,YMove,XStart,XMove,ZoomLevel,Path]
def show_prefs():
buttonthumbsize = Blender.Draw.Create(Blender.drawmap[0]);
buttonCameraHeight = Blender.Draw.Create(Blender.drawmap[1])
buttonYStart = Blender.Draw.Create(Blender.drawmap[2])
buttonYMove = Blender.Draw.Create(Blender.drawmap[3])
buttonXStart = Blender.Draw.Create(Blender.drawmap[4])
buttonXMove = Blender.Draw.Create(Blender.drawmap[5])
buttonZoomLevel = Blender.Draw.Create(Blender.drawmap[6])
buttonPath = Blender.Draw.Create(Blender.drawmap[7])
block = []
block.append(("Image Size", buttonthumbsize, 0, 500))
block.append(("Camera Height", buttonCameraHeight, -0, 10))
block.append(("Y Start", buttonYStart, -10, 10))
block.append(("Y Move", buttonYMove, 0, 5))
block.append(("X Start", buttonXStart,-10, 10))
block.append(("X Move", buttonXMove, 0, 5))
block.append(("Zoom Level", buttonZoomLevel, 1, 10))
block.append(("Export Path", buttonPath,0,200,"The Path to save the tiles"))
retval = Blender.Draw.PupBlock("Draw Map: Preferences" , block)
if retval:
Blender.drawmap[0] = buttonthumbsize.val
Blender.drawmap[1] = buttonCameraHeight.val
Blender.drawmap[2] = buttonYStart.val
Blender.drawmap[3] = buttonYMove.val
Blender.drawmap[4] = buttonXStart.val
Blender.drawmap[5] = buttonXMove.val
Blender.drawmap[6] = buttonZoomLevel.val
Blender.drawmap[7] = buttonPath.val
Export()
def Export():
scn = Scene.GetCurrent()
context = scn.getRenderingContext()
def cutStr(str): #cut off path leaving name
c = str.find("\\")
while c != -1:
c = c + 1
str = str[c:]
c = str.find("\\")
str = str[:-6]
return str
#variables from gui:
thumbsize,CameraHeight,YStart,YMove,XStart,XMove,ZoomLevel,Path = Blender.drawmap
XMove = XMove / ZoomLevel
YMove = YMove / ZoomLevel
Camera = Scene.GetCurrent().getCurrentCamera()
Camera.LocZ = CameraHeight / ZoomLevel
YStart = YStart + (YMove / 2)
XStart = XStart + (XMove / 2)
#Point it straight down
Camera.RotX = 0
Camera.RotY = 0
Camera.RotZ = 0
TileCount = 4**ZoomLevel
#Because the first thing we do is move the camera, start it off the map
Camera.LocY = YStart - YMove
for i in range(0,TileCount):
Camera.LocY = Camera.LocY + YMove
Camera.LocX = XStart - XMove
for j in range(0,TileCount):
Camera.LocX = Camera.LocX + XMove
Render.EnableDispWin()
context.extensions = True
context.renderPath = Path
#setting thumbsize
context.imageSizeX(thumbsize)
context.imageSizeY(thumbsize)
#could be put into a gui.
context.imageType = Render.PNG
context.enableOversampling(0)
#render
context.render()
#save image
ZasString = '%s' %(int(ZoomLevel))
XasString = '%s' %(int(j+1))
YasString = '%s' %(int((3-i)+1))
context.saveRenderedImage("Z" + ZasString + "X" + XasString + "Y" + YasString)
#close the windows
Render.CloseRenderWindow()
try:
type(Blender.drawmap)
except:
#print 'initialize extern variables'
init()
show_prefs()
This was relatively simple in the end.
I scaled up the model so that 1 tile on the map was 1 grid in blender.
Set the camera to be orthographic.
Set the scale on the camera to 1 for the highest zoom, 4 for the next one, 16 for the next one and so on.
Updated the start coordinates and move values accordingly.

Categories

Resources