Repository navigation
Description
Python 2.7.5, NumPy 1.7.1, SciPy 0.13.0, Matplotlib 1.3.1
This is a script to simulate the rolling of a coin( a circle) on a surface without slipping in 3 dimensions. I tried to paste on a shorter version of my code but it is not easy because of the physics part. Please bare with me. My question relates to the animation part. If one uncomments the last two lines related to function animation just before the pyplot.show(), we will get a colored circle. But if we keep the function animation, the circle in motion will only have one color. The circle is a 3D line object and, it is being updated by update_line function. It seems the color information is left behind during the update_line or animation period. I tried many methods like, passing in the color argument into the update_line function and use the set_c method, or passing in a colormap and a scale. None of them worked for me. Does anyone know how to give the rolling circle a color gradient/cycle, to make it looks more like a rolling without slipping motion? Thanks in advance! Tony :)
import numpy as np
from matplotlib import pyplot
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.animation as animation
def rotation_matrix(axis,theta):
axis = axis/np.sqrt(np.dot(axis,axis))
a = np.cos(theta/2)
b,c,d = axis*np.sin(theta/2)
return np.array([[a*a+b*b-c*c-d*d, 2*(b*c-a*d), 2*(b*d+a*c)],
[2*(b*c+a*d), a*a+c*c-b*b-d*d, 2*(c*d-a*b)],
[2*(b*d-a*c), 2*(c*d+a*b), a*a+d*d-b*b-c*c]])
xx = 5
R = 5*np.sqrt(2)
ncp = 10 # number of 'new' CP, not including origin
onetheta = 30 # the angle of triangles which approximate a circle
angles = range(0,360+onetheta,onetheta) #[0,2,...,360]
theta = np.array(angles) * np.pi / 180 #in radians
C = np.zeros((ncp+1,3,3))
# Set the orientation of z w.r.t lab_z
leananl=np.pi/5
C[0,:,:] = np.dot(rotation_matrix(np.array([1,0,0]),leananl),np.eye(3))
Cprime = np.zeros((ncp+1,3,3))
CM = np.zeros((ncp+1,3)) #CM position vector array
CM[0,:]= R*C[0,:,1] #CM(t0)
CMprime = np.zeros((ncp+1,3))
z = np.array([0,0,1])
cirCP = np.zeros((len(angles),3,ncp)) #circle of the coin
rotheta = onetheta*np.pi/180 # theta
CP = np.zeros((ncp+1,3))
CPprime = np.zeros((ncp+1,3))
lowerangle = -np.radians(np.linspace(0,ncp,ncp)/ncp)
omega_z = np.zeros(ncp+1)
w = np.zeros((ncp+1,3))
w[:,2]=w[:,2]+0.0005
w[:,1]=w[:,1]+0.001
w[:,0]=w[:,0]-0.0005
for j in range(ncp):
betaj=np.pi/2 - np.arccos(np.dot(C[j,:,1],z))
alphaangl = np.arcsin(np.sin(rotheta/2)/np.cos(betaj))
kappaj = 2*alphaangl
phi = np.arccos(np.cos(alphaangl)/np.cos(np.radians(onetheta/2)))
twodt=2*phi/w[j+1,1] #phi/wy
Avecinspace = np.dot(rotation_matrix(z,kappaj/2),
C[j,:,0]*R*np.sin(rotheta/2)*2)
Cprime[j,:,:] = np.dot(rotation_matrix(z,kappaj),C[j,:,:])
C[j+1,:,:] = np.dot(rotation_matrix(Cprime[j,:,0],w[j+1,0]*twodt),Cprime[j,:,:])
CPprime[j,:] = CP[j,:] +Avecinspace
CP[j+1,:] = CPprime[j,:] + Cprime[j,:,0]*w[j+1,2]*twodt*R
CMprime[j,:]=CM[j,:] + Cprime[j,:,0]*w[j+1,2]*twodt*R
CM[j+1,:] = CP[j+1,:] + C[j+1,:,1]*R
for i in range(len(angles)):
cirCP[i,:,j] = np.dot(rotation_matrix(C[j,:,2],theta[i]),CP[j,:]-CM[j,:]) + CM[j,:]
omega_z[j+1] = omega_z[j] + w[j+1,2]*twodt
### plot figure
fig1 = pyplot.figure(1)
ax = p3.Axes3D(fig1)
ax.view_init(elev=35, azim=-45)
def update_line(x, line, cirCP, CP):
for indl, linein in enumerate(line):
for li, angx1 in zip(linein,range(len(angles))):
li.set_data(cirCP[0:2+indl,0,x],cirCP[0:2+indl,1,x])
li.set_3d_properties(cirCP[0:2+indl,2,x])
return line
line = [ax.plot(*[cirCP[j:j+2,i,0] for i in range(3)]) for j in range(len(angles))]
ax.set_xbound(-10,10)
ax.set_ybound(0,20)
ax.set_zbound(0,10)
line_ani = animation.FuncAnimation(fig1, update_line, ncp, fargs=(line,cirCP,CP),
interval=500, blit=False,repeat=True)
pyplot.show()
Activity
WeatherGod commentedon Aug 12, 2014
Confirmed (with mpl 1.2.1, though). I will need to double-check with the upcoming 1.4.0 release. I am not sure why this is happening as the Line3D code does not touch the color information. Indeed, if you put a "print li.get_color()" into the update_lines() function, you will see that it will still report colors and not grayscale values.
whymranderson commentedon Aug 14, 2014
Thank you very much for checking this.
tacaswell commentedon Aug 14, 2014
@WeatherGod I am inclined to not make this a blocker for 1.4.0 given how long it has been outstanding. Re-tag if you disagree.
WeatherGod commentedon Aug 14, 2014
Absolutely, it is not a blocker. And it is certainly a puzzler, too..
On Thu, Aug 14, 2014 at 11:56 AM, Thomas A Caswell <[email protected]
durden commentedon Aug 14, 2014
I've seen an issue that I think is related to this using 1.3.1. It seems as though calling
set_coloron aPatch3DCollectionis completely ignored. I only see the issue when using a 3D plot.Below is a snippet similar to what I've been trying. You can comment the lines at the bottom to alternate which version (2d or 3d) you're testing. The same mechanism works for a 2d scatter plot, but not for a 3d one.
The goal is to add a new point on each animation. Then, change all older points to a different color. It's not optimal and will constantly change the color of old points even if they've already been changed. However, it clearly demonstrates that the call to set_color doesn't have any effect even though it's a somewhat silly example.
WeatherGod commentedon Aug 14, 2014
Actually, that is a separate issue that has since been resolved, I believe
(I haven't confirmed with your example against the upcoming 1.4.0 release).
Patch3D objects weren't maintaining their colors correctly. These are
Line3D objects, and they don't do anything with colors, just pass them down
to the 2D versions. As I noted before, if you query the objects throughout
the animation, they report back the correct colors, it is just the drawing
that fails to use those colors, it seems.
On Thu, Aug 14, 2014 at 5:03 PM, Luke Lee [email protected] wrote:
durden commentedon Aug 14, 2014
Ah, thanks for the update. Is there a commit or issue I can look into for that? I'm curious as to how it was fixed. Also, when is 1.4.0 slated for public release?
WeatherGod commentedon Aug 14, 2014
I don't have a link handy. In fact, the particular fix I was thinking off
was already in v1.3.1, so this might actually be a legitimate bug. We are
currently in release canidate mode, and you can get downloadable binaries
from matplotlib's sourceforge page. If you are still experiencing the
problem, then file a new bug report as it is involving a different mplot3d
object type. If it is all related, we can join the reports later.
On Thu, Aug 14, 2014 at 5:56 PM, Luke Lee [email protected] wrote:
durden commentedon Aug 15, 2014
I've tested my snippet with the 1.4.x release candidate, and it still fails. I've created a new bug for this issue.
whymranderson commentedon Aug 20, 2014
Yet again I think I have made a mistake!(another embarrassing moment :p ) After I changed the
update_linefunction to the following, (changing only the start of the slicing index on the variable cirCP from 0 to indl) it seems to work just fine now! Still special thanks to WeatherGod for pointing out the color reporting issue that made me decide to keep digging into it. And also many many thanks to everyone for checking the code for me. It is such a small thing that it hides so well and I really had to go ahugecircle to find it... Really apologize for reporting a wrong issue and it's damage. I am still quite new here so I won't be able to comment the other Patch3DCollection issue. Still appreciate if someone can confirm the following adjusted code is fine. Then maybe I should close this issue?whymranderson commentedon Aug 20, 2014
I guess it is another great lesson or example of showing the important of
MWE(minimal working example). :)WeatherGod commentedon Aug 20, 2014
Ah, I see what was happening! The last line being drawn was yellow (well,
actually, that nasty, ugly dull "yellow"). With the update code, that
yellow line had all of the segments of the coin and was being drawn on top
of all of the other colored segments. I tried out the fix, and it seems to
work fine. I think the only question is if it is intended for the colors of
the segments to change. Picturing how a coin settles, the edges mostly only
move up and down, but this visualization gives the impression that the coin
is rotating significantly. Perhaps there is still some other error left in
the code?
On Wed, Aug 20, 2014 at 5:51 AM, whymranderson [email protected]
wrote:
whymranderson commentedon Aug 21, 2014
:) You are right. The code there does not fully contain the part that tracks the rolling without slipping motion. This code here does. I wasn't able to fix this part because of my mistake that makes the circle uni-color. Now that problem is fix, I also fix this rolling part too. Feel free to give the simulation a try. :) But I have to clearly indicate, I am still working on this, so it is still an artificial simulation, even though it got the rigid body equation of motion in it. Thanks a lot for the feedback :)