[yt-svn] commit/yt: 4 new changesets
Bitbucket
commits-noreply at bitbucket.org
Fri Jun 22 12:04:32 PDT 2012
4 new commits in yt:
https://bitbucket.org/yt_analysis/yt/changeset/b24c046a4660/
changeset: b24c046a4660
branch: yt
user: jwise77
date: 2012-05-08 18:49:59
summary: Adding more arguments and control over several eps_writer calls.
affected #: 1 file
diff -r c0acbf8d43778f223f414504048c0a3278bbfb24 -r b24c046a46606662f3d2c773bbebbe781793e912 yt/visualization/eps_writer.py
--- a/yt/visualization/eps_writer.py
+++ b/yt/visualization/eps_writer.py
@@ -68,7 +68,8 @@
#=============================================================================
def axis_box(self, xrange=(0,1), yrange=(0,1), xlabel="", ylabel="",
- xlog=False, ylog=False, tickcolor=None, bare_axes=False,
+ xlog=False, ylog=False, xdata=None, ydata=None,
+ tickcolor=None, bare_axes=False,
pos=(0,0), xaxis_side=0, yaxis_side=0, size=None):
r"""Draws an axis box in the figure.
@@ -239,20 +240,28 @@
(width=psize[0], height=psize[1],
x=xaxis, y=yaxis, x2=xaxis2, y2=yaxis2,
xpos=pos[0], ypos=pos[1])
- self.canvas.plot(blank_data)
+ if xdata == None:
+ self.canvas.plot(blank_data)
+ else:
+ data = pyx.graph.data.points(na.array([xdata, ydata]).T, x=1, y=2)
+ self.canvas.plot(data, [pyx.graph.style.line([pyx.style.linewidth.Thick])])
else:
plot = pyx.graph.graphxy \
(width=psize[0], height=psize[1],
x=xaxis, y=yaxis, x2=xaxis2, y2=yaxis2,
xpos=pos[0], ypos=pos[1])
- plot.plot(blank_data)
+ if xdata == None:
+ plot.plot(blank_data)
+ else:
+ data = pyx.graph.data.points(na.array([xdata, ydata]).T, x=1, y=2)
+ plot.plot(data, [pyx.graph.style.line([pyx.style.linewidth.Thick])])
self.canvas.insert(plot)
self.axes_drawn = True
#=============================================================================
def axis_box_yt(self, plot, units=None, bare_axes=False,
- tickcolor=None, **kwargs):
+ tickcolor=None, xlabel=None, ylabel=None, **kwargs):
r"""Wrapper around DualEPS.axis_box to automatically fill in the
axis ranges and labels from a yt plot.
@@ -295,8 +304,14 @@
_ylabel = ""
else:
units = units.replace('mpc', 'Mpc')
- _xlabel = '%s (%s)' % (x_names[plot.data.axis], units)
- _ylabel = '%s (%s)' % (y_names[plot.data.axis], units)
+ if xlabel != None:
+ _xlabel = xlabel
+ else:
+ _xlabel = '%s (%s)' % (x_names[plot.data.axis], units)
+ if ylabel != None:
+ _ylabel = ylabel
+ else:
+ _ylabel = '%s (%s)' % (y_names[plot.data.axis], units)
if tickcolor == None:
_tickcolor = pyx.color.cmyk.white
else:
@@ -308,8 +323,14 @@
_xlabel = ""
_ylabel = ""
else:
- _xlabel = plot._x_label
- _ylabel = plot._y_label
+ if xlabel != None:
+ _xlabel = xlabel
+ else:
+ _xlabel = plot._x_label
+ if ylabel != None:
+ _ylabel = ylabel
+ else:
+ _ylabel = plot._y_label
if tickcolor == None:
_tickcolor = None
if tickcolor != None:
@@ -464,9 +485,13 @@
print "orientation %s unknown" % orientation
return
+ # If shrink is a scalar, then convert into tuple
+ if not isinstance(shrink, (tuple,list)):
+ shrink = (shrink, shrink)
+
# Scale the colorbar
- shift = (0.5*(1.0-shrink)*size[0], 0.5*(1.0-shrink)*size[1])
- size = (size[0] * shrink, size[1] * shrink)
+ shift = (0.5*(1.0-shrink[0])*size[0], 0.5*(1.0-shrink[1])*size[1])
+ size = (size[0] * shrink[0], size[1] * shrink[1])
origin = (origin[0] + shift[0], origin[1] + shift[1])
# Convert the colormap into a string
@@ -658,7 +683,8 @@
def title_box(self, text, color=pyx.color.cmyk.black,
bgcolor=pyx.color.cmyk.white, loc=(0.02,0.98),
halign=pyx.text.halign.left,
- valign=pyx.text.valign.top):
+ valign=pyx.text.valign.top,
+ text_opts=[]):
r"""Inserts a box with text in the current figure.
Parameters
@@ -686,7 +712,7 @@
"""
tbox = self.canvas.text(self.figsize[0]*loc[0],
self.figsize[1]*loc[1],
- text, [color, valign, halign])
+ text, [color, valign, halign] + text_opts)
if bgcolor != None:
tpath = tbox.bbox().enlarged(2*pyx.unit.x_pt).path()
self.canvas.draw(tpath, [pyx.deco.filled([bgcolor]),
@@ -723,9 +749,11 @@
#=============================================================================
def multiplot(ncol, nrow, yt_plots=None, images=None, xranges=None,
- yranges=None, xlabels=None, ylabels=None, colorbars=None,
+ yranges=None, xlabels=None, ylabels=None,
+ xdata=None, ydata=None, colorbars=None,
shrink_cb=0.95, figsize=(8,8), margins=(0,0), titles=None,
savefig=None, format="eps", yt_nocbar=False, bare_axes=False,
+ xaxis_flags=None, yaxis_flags=None,
cb_flags=None):
r"""Convenience routine to create a multi-panel figure from yt plots or
JPEGs. The images are first placed from the origin, and then
@@ -844,17 +872,42 @@
yaxis = 1
else:
yaxis = -1
+ if xdata == None:
+ _xdata = None
+ else:
+ _xdata = xdata[index]
+ if ydata == None:
+ _ydata = None
+ else:
+ _ydata = ydata[index]
+ if xaxis_flags != None:
+ if xaxis_flags[index] != None:
+ xaxis = xaxis_flags[index]
+ if yaxis_flags != None:
+ if yaxis_flags[index] != None:
+ yaxis = yaxis_flags[index]
if _yt:
+ if xlabels != None:
+ xlabel = xlabels[i]
+ else:
+ xlabel = None
+ if ylabels != None:
+ ylabel = ylabels[j]
+ else:
+ ylabel = None
d.insert_image_yt(yt_plots[index], pos=(xpos, ypos))
d.axis_box_yt(yt_plots[index], pos=(xpos, ypos),
bare_axes=bare_axes, xaxis_side=xaxis,
- yaxis_side=yaxis)
+ yaxis_side=yaxis,
+ xlabel=xlabel, ylabel=ylabel,
+ xdata=_xdata, ydata=_ydata)
else:
d.insert_image(images[index], pos=(xpos,ypos))
d.axis_box(pos = (xpos, ypos),
xrange=xranges[index], yrange=yranges[index],
xlabel=xlabels[i], ylabel=ylabels[j],
- bare_axes=bare_axes, xaxis_side=xaxis, yaxis_side=yaxis)
+ bare_axes=bare_axes, xaxis_side=xaxis, yaxis_side=yaxis,
+ xdata=_xdata, ydata=_ydata)
if titles != None:
if titles[index] != None:
d.title_box(titles[index],
https://bitbucket.org/yt_analysis/yt/changeset/1d422a9bc9e3/
changeset: 1d422a9bc9e3
branch: yt
user: jwise77
date: 2012-05-08 18:50:37
summary: Merged.
affected #: 1 file
diff -r 9ece5c1017fdb66c6da89c01aa2ce941ce1fc985 -r 1d422a9bc9e3bc0c7af24ae9f97b2a1c75cf64a1 yt/visualization/eps_writer.py
--- a/yt/visualization/eps_writer.py
+++ b/yt/visualization/eps_writer.py
@@ -68,7 +68,8 @@
#=============================================================================
def axis_box(self, xrange=(0,1), yrange=(0,1), xlabel="", ylabel="",
- xlog=False, ylog=False, tickcolor=None, bare_axes=False,
+ xlog=False, ylog=False, xdata=None, ydata=None,
+ tickcolor=None, bare_axes=False,
pos=(0,0), xaxis_side=0, yaxis_side=0, size=None):
r"""Draws an axis box in the figure.
@@ -239,20 +240,28 @@
(width=psize[0], height=psize[1],
x=xaxis, y=yaxis, x2=xaxis2, y2=yaxis2,
xpos=pos[0], ypos=pos[1])
- self.canvas.plot(blank_data)
+ if xdata == None:
+ self.canvas.plot(blank_data)
+ else:
+ data = pyx.graph.data.points(na.array([xdata, ydata]).T, x=1, y=2)
+ self.canvas.plot(data, [pyx.graph.style.line([pyx.style.linewidth.Thick])])
else:
plot = pyx.graph.graphxy \
(width=psize[0], height=psize[1],
x=xaxis, y=yaxis, x2=xaxis2, y2=yaxis2,
xpos=pos[0], ypos=pos[1])
- plot.plot(blank_data)
+ if xdata == None:
+ plot.plot(blank_data)
+ else:
+ data = pyx.graph.data.points(na.array([xdata, ydata]).T, x=1, y=2)
+ plot.plot(data, [pyx.graph.style.line([pyx.style.linewidth.Thick])])
self.canvas.insert(plot)
self.axes_drawn = True
#=============================================================================
def axis_box_yt(self, plot, units=None, bare_axes=False,
- tickcolor=None, **kwargs):
+ tickcolor=None, xlabel=None, ylabel=None, **kwargs):
r"""Wrapper around DualEPS.axis_box to automatically fill in the
axis ranges and labels from a yt plot.
@@ -295,8 +304,14 @@
_ylabel = ""
else:
units = units.replace('mpc', 'Mpc')
- _xlabel = '%s (%s)' % (x_names[plot.data.axis], units)
- _ylabel = '%s (%s)' % (y_names[plot.data.axis], units)
+ if xlabel != None:
+ _xlabel = xlabel
+ else:
+ _xlabel = '%s (%s)' % (x_names[plot.data.axis], units)
+ if ylabel != None:
+ _ylabel = ylabel
+ else:
+ _ylabel = '%s (%s)' % (y_names[plot.data.axis], units)
if tickcolor == None:
_tickcolor = pyx.color.cmyk.white
else:
@@ -308,8 +323,14 @@
_xlabel = ""
_ylabel = ""
else:
- _xlabel = plot._x_label
- _ylabel = plot._y_label
+ if xlabel != None:
+ _xlabel = xlabel
+ else:
+ _xlabel = plot._x_label
+ if ylabel != None:
+ _ylabel = ylabel
+ else:
+ _ylabel = plot._y_label
if tickcolor == None:
_tickcolor = None
if tickcolor != None:
@@ -464,9 +485,13 @@
print "orientation %s unknown" % orientation
return
+ # If shrink is a scalar, then convert into tuple
+ if not isinstance(shrink, (tuple,list)):
+ shrink = (shrink, shrink)
+
# Scale the colorbar
- shift = (0.5*(1.0-shrink)*size[0], 0.5*(1.0-shrink)*size[1])
- size = (size[0] * shrink, size[1] * shrink)
+ shift = (0.5*(1.0-shrink[0])*size[0], 0.5*(1.0-shrink[1])*size[1])
+ size = (size[0] * shrink[0], size[1] * shrink[1])
origin = (origin[0] + shift[0], origin[1] + shift[1])
# Convert the colormap into a string
@@ -658,7 +683,8 @@
def title_box(self, text, color=pyx.color.cmyk.black,
bgcolor=pyx.color.cmyk.white, loc=(0.02,0.98),
halign=pyx.text.halign.left,
- valign=pyx.text.valign.top):
+ valign=pyx.text.valign.top,
+ text_opts=[]):
r"""Inserts a box with text in the current figure.
Parameters
@@ -686,7 +712,7 @@
"""
tbox = self.canvas.text(self.figsize[0]*loc[0],
self.figsize[1]*loc[1],
- text, [color, valign, halign])
+ text, [color, valign, halign] + text_opts)
if bgcolor != None:
tpath = tbox.bbox().enlarged(2*pyx.unit.x_pt).path()
self.canvas.draw(tpath, [pyx.deco.filled([bgcolor]),
@@ -723,9 +749,11 @@
#=============================================================================
def multiplot(ncol, nrow, yt_plots=None, images=None, xranges=None,
- yranges=None, xlabels=None, ylabels=None, colorbars=None,
+ yranges=None, xlabels=None, ylabels=None,
+ xdata=None, ydata=None, colorbars=None,
shrink_cb=0.95, figsize=(8,8), margins=(0,0), titles=None,
savefig=None, format="eps", yt_nocbar=False, bare_axes=False,
+ xaxis_flags=None, yaxis_flags=None,
cb_flags=None):
r"""Convenience routine to create a multi-panel figure from yt plots or
JPEGs. The images are first placed from the origin, and then
@@ -844,17 +872,42 @@
yaxis = 1
else:
yaxis = -1
+ if xdata == None:
+ _xdata = None
+ else:
+ _xdata = xdata[index]
+ if ydata == None:
+ _ydata = None
+ else:
+ _ydata = ydata[index]
+ if xaxis_flags != None:
+ if xaxis_flags[index] != None:
+ xaxis = xaxis_flags[index]
+ if yaxis_flags != None:
+ if yaxis_flags[index] != None:
+ yaxis = yaxis_flags[index]
if _yt:
+ if xlabels != None:
+ xlabel = xlabels[i]
+ else:
+ xlabel = None
+ if ylabels != None:
+ ylabel = ylabels[j]
+ else:
+ ylabel = None
d.insert_image_yt(yt_plots[index], pos=(xpos, ypos))
d.axis_box_yt(yt_plots[index], pos=(xpos, ypos),
bare_axes=bare_axes, xaxis_side=xaxis,
- yaxis_side=yaxis)
+ yaxis_side=yaxis,
+ xlabel=xlabel, ylabel=ylabel,
+ xdata=_xdata, ydata=_ydata)
else:
d.insert_image(images[index], pos=(xpos,ypos))
d.axis_box(pos = (xpos, ypos),
xrange=xranges[index], yrange=yranges[index],
xlabel=xlabels[i], ylabel=ylabels[j],
- bare_axes=bare_axes, xaxis_side=xaxis, yaxis_side=yaxis)
+ bare_axes=bare_axes, xaxis_side=xaxis, yaxis_side=yaxis,
+ xdata=_xdata, ydata=_ydata)
if titles != None:
if titles[index] != None:
d.title_box(titles[index],
https://bitbucket.org/yt_analysis/yt/changeset/70f267d2671f/
changeset: 70f267d2671f
branch: yt
user: jwise77
date: 2012-06-22 17:31:54
summary: Merging changes from mainline
affected #: 143 files
Diff too large to display.
https://bitbucket.org/yt_analysis/yt/changeset/f6cc8e9297e8/
changeset: f6cc8e9297e8
branch: yt
user: jwise77
date: 2012-06-22 20:56:40
summary: Adding a class that can create camera paths from splines fit to
keyframes. It also has the ability to order the keyframes to decrease
the distance travelled.
affected #: 2 files
diff -r 70f267d2671fa4734f4c48d9eda3ead5c615020e -r f6cc8e9297e8b0a4250d5d975f8f0abf9ce62fcc yt/visualization/volume_rendering/camera_path.py
--- /dev/null
+++ b/yt/visualization/volume_rendering/camera_path.py
@@ -0,0 +1,340 @@
+"""
+Create smooth camera paths from keyframes.
+
+Author: John Wise <jwise at physics.gatech.edu>
+Affiliation: Georgia Tech
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2012 John Wise. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import random
+import numpy as na
+from .create_spline import create_spline
+
+class Keyframes(object):
+ def __init__(self, x, y, z=None, north_vectors=None, up_vectors=None,
+ times=None, niter=50000, init_temp=10.0, alpha=0.999,
+ fixed_start=False):
+ r"""Keyframes for camera path generation.
+
+ From a set of keyframes with position and optional up and
+ north vectors, an interpolated camera path is generated.
+
+ Parameters
+ ----------
+ x : array_like
+ The x positions of the keyframes
+ y : array_like
+ The y positions of the keyframes
+ z : array_like, optional
+ The z positions of the keyframes. Default: 0.0
+ north_vectors : array_like, optional
+ The north vectors of the keyframes. Default: None
+ up_vectors : array_like, optional
+ The up vectors of the keyframes. Default: None
+ times : array_like, optional
+ The times of the keyframes. Default: arange(N)
+ niter : integer, optional
+ Maximum number of iterations to find solution. Default: 50000
+ init_temp : float, optional
+ Intital temperature for simulated annealing when finding a
+ solution. Lower initial temperatures result in an initial solution
+ in first several iterations that changes more rapidly. Default: 10.0
+ alpha : float, optional
+ Exponent in cooling function in simulated annealing. Must be < 1.
+ In each iteration, the temperature_new = temperature_old * alpha.
+ Default: 0.999
+ fixed_start: boolean, optional
+ If true, the first point never changes when searching for shortest
+ path. Default: False
+
+ Examples
+ --------
+
+ >>> import numpy as na
+ >>> import matplotlib.pyplot as plt
+ >>> from yt.visualization.volume_rendering.camera_path import *
+
+ # Make a camera path from 10 random (x,y,z) keyframes
+ >>> data = na.random.random.((10,3))
+ >>> kf = Keyframes(data[:,0], data[:,1], data[:,2])
+ >>> path = kf.create_path(250, shortest_path=False)
+
+ # Plot the keyframes in the x-y plane and camera path
+ plt.plot(kf.pos[:,0], kf.pos[:,1], 'ko')
+ plt.plot(path['position'][:,0], path['position'][:,1])
+ plt.savefig('path.png')
+ """
+ Nx = len(x)
+ Ny = len(y)
+ if z != None:
+ Nz = len(z)
+ ndims = 3
+ else:
+ Nz = 1
+ ndims = 2
+ if Nx*Ny*Nz != Nx**ndims:
+ print "Need Nx (%d) == Ny (%d) == Nz (%d)" % (Nx, Ny, Nz)
+ sys.exit()
+ self.nframes = Nx
+ self.pos = na.zeros((Nx,3))
+ self.pos[:,0] = x
+ self.pos[:,1] = y
+ if z != None:
+ self.pos[:,2] = z
+ else:
+ self.pos[:,2] = 0.0
+ self.north_vectors = north_vectors
+ self.up_vectors = up_vectors
+ if times == None:
+ self.times = na.arange(self.nframes)
+ else:
+ self.times = times
+ self.cartesian_matrix()
+ self.setup_tsp(niter, init_temp, alpha, fixed_start)
+
+ def setup_tsp(self, niter=50000, init_temp=10.0, alpha=0.999,
+ fixed_start=False):
+ r"""Setup parameters for Travelling Salesman Problem.
+
+ Parameters
+ ----------
+ niter : integer, optional
+ Maximum number of iterations to find solution. Default: 50000
+ init_temp : float, optional
+ Intital temperature for simulated annealing when finding a
+ solution. Lower initial temperatures result in an initial solution
+ in first several iterations that changes more rapidly. Default: 10.0
+ alpha : float, optional
+ Exponent in cooling function in simulated annealing. Must be < 1.
+ In each iteration, the temperature_new = temperature_old * alpha.
+ Default: 0.999
+ fixed_start: boolean, optional
+ If true, the first point never changes when searching for shortest
+ path. Default: False
+ """
+ # randomize tour
+ self.tour = range(self.nframes)
+ na.random.shuffle(self.tour)
+ if fixed_start:
+ first = self.tour.index(0)
+ self.tour[0], self.tour[first] = self.tour[first], self.tour[0]
+ self.max_iterations = niter
+ self.initial_temp = init_temp
+ self.alpha = alpha
+ self.fixed_start = fixed_start
+ self.best_score = None
+ self.best = None
+
+ def set_times(self, times):
+ self.times = times
+
+ def rand_seq(self):
+ r"""
+ Generates values in random order, equivlanet to using shuffle
+ in random without generation all values at once.
+ """
+ values = range(self.nframes)
+ for i in xrange(self.nframes):
+ # pick a random index into remaining values
+ j = i + int(random.random() * (self.nframes-i))
+ # swap the values
+ values[j], values[i] = values[i], values[j]
+ # return the swapped value
+ yield values[i]
+
+ def all_pairs(self):
+ r"""
+ Generates all (i,j) pairs for (i,j) for 0-size
+ """
+ for i in self.rand_seq():
+ for j in self.rand_seq():
+ yield (i,j)
+
+ def reversed_sections(self, tour):
+ r"""
+ Generator to return all possible variations where a section
+ between two cities are swapped.
+ """
+ for i,j in self.all_pairs():
+ if i == j: continue
+ copy = tour[:]
+ if i < j:
+ copy[i:j+1] = reversed(tour[i:j+1])
+ else:
+ copy[i+1:] = reversed(tour[:j])
+ copy[:j] = reversed(tour[i+1:])
+ if self.fixed_start:
+ ind = copy.index(0)
+ copy[0], copy[ind] = copy[ind], copy[0]
+ if copy != tour: # no point return the same tour
+ yield copy
+
+ def cartesian_matrix(self):
+ r"""
+ Create a distance matrix for the city coords that uses
+ straight line distance
+ """
+ self.dist_matrix = na.zeros((self.nframes, self.nframes))
+ xmat = na.zeros((self.nframes, self.nframes))
+ xmat[:,:] = self.pos[:,0]
+ dx = xmat - xmat.T
+ ymat = na.zeros((self.nframes, self.nframes))
+ ymat[:,:] = self.pos[:,1]
+ dy = ymat - ymat.T
+ zmat = na.zeros((self.nframes, self.nframes))
+ zmat[:,:] = self.pos[:,2]
+ dz = zmat - zmat.T
+ self.dist_matrix = na.sqrt(dx*dx + dy*dy + dz*dz)
+
+ def tour_length(self, tour):
+ r"""
+ Calculate the total length of the tour based on the distance
+ matrix
+ """
+ total = 0
+ num_cities = len(tour)
+ for i in range(num_cities):
+ j = (i+1) % num_cities
+ city_i = tour[i]
+ city_j = tour[j]
+ total += self.dist_matrix[city_i, city_j]
+ return -total
+
+ def cooling(self):
+ T = self.initial_temp
+ while True:
+ yield T
+ T = self.alpha * T
+
+ def prob(self, prev, next, temperature):
+ if next > prev:
+ return 1.0
+ else:
+ return na.exp( -abs(next-prev) / temperature )
+
+ def get_shortest_path(self):
+ r"""Determine shortest path between all keyframes.
+
+ Parameters
+ ----------
+ None.
+ """
+ self.setup_tsp(niter, init_temp, alpha, fixed_start)
+ num_eval = 1
+ cooling_schedule = self.cooling()
+ current = self.tour
+ current_score = self.tour_length(current)
+ for temperature in cooling_schedule:
+ done = False
+ # Examine moves around the current position
+ for next in self.reversed_sections(current):
+ if num_eval >= self.max_iterations:
+ done = True
+ break
+ next_score = self.tour_length(next)
+ num_eval += 1
+
+ # Anneal. Accept new solution if a random number is
+ # greater than our "probability".
+ p = self.prob(current_score, next_score, temperature)
+ if random.random() < p:
+ current = next
+ self.current_score = next_score
+ if self.current_score > self.best_score:
+ #print num_eval, self.current_score, self.best_score, current
+ self.best_score = self.current_score
+ self.best = current
+ break
+
+ if done:
+ break
+ self.pos = self.pos[self.tour,:]
+ if self.north_vectors != None:
+ self.north_vectors = self.north_vectors[self.tour]
+ if self.up_vectors != None:
+ self.up_vectors = self.up_vectors[self.tour]
+
+ def create_path(self, npoints, path_time=None, tension=0.5, shortest_path=False):
+ r"""Create a interpolated camera path from keyframes.
+
+ Parameters
+ ----------
+ npoints : integer
+ Number of points to interpolate from keyframes
+ path_time : array_like, optional
+ Times of interpolated points. Default: Linearly spaced
+ tension : float, optional
+ Controls how sharp of a curve the spline takes. A higher tension
+ allows for more sharp turns. Default: 0.5
+ shortest_path : boolean, optional
+ If true, estimate the shortest path between the keyframes.
+ Default: False
+
+ Returns
+ -------
+ path : dict
+ Dictionary (time, position, north_vectors, up_vectors) of camera
+ path. Also saved to self.path.
+ """
+ self.npoints = npoints
+ self.path = {"time": na.zeros(npoints),
+ "position": na.zeros((npoints, 3)),
+ "north_vectors": na.zeros((npoints,3)),
+ "up_vectors": na.zeros((npoints,3))}
+ if shortest_path:
+ self.get_shortest_path()
+ if path_time == None:
+ path_time = na.linspace(0, self.nframes, npoints)
+ self.path["time"] = path_time
+ for dim in range(3):
+ self.path["position"][:,dim] = create_spline(self.times, self.pos[:,dim],
+ path_time, tension=tension)
+ if self.north_vectors != None:
+ self.path["north_vectors"][:,dim] = \
+ create_spline(self.times, self.north_vectors[:,dim],
+ path_time, tension=tension)
+ if self.up_vectors != None:
+ self.path["up_vectors"][:,dim] = \
+ create_spline(self.times, self.up_vectors[:,dim],
+ path_time, tension=tension)
+ return self.path
+
+ def write_path(self, filename="path.dat"):
+ r"""Writes camera path to ASCII file
+
+ Parameters
+ ----------
+ filename : string, optional
+ Filename containing the camera path. Default: path.dat
+ """
+ fp = open(filename, "w")
+ fp.write("#%11s %12s %12s %12s %12s %12s %12s %12s %12s\n" %
+ ("x", "y", "z", "north_x", "north_y", "north_z",
+ "up_x", "up_y", "up_z"))
+ for i in range(self.npoints):
+ fp.write("%.12f %.12f %.12f %.12f %.12f %.12f %.12f %.12f %.12f\n" %
+ (self.path["position"][i,0], self.path["position"][i,1],
+ self.path["position"][i,2],
+ self.path["north_vectors"][i,0], self.path["north_vectors"][i,1],
+ self.path["north_vectors"][i,2],
+ self.path["up_vectors"][i,0], self.path["up_vectors"][i,1],
+ self.path["up_vectors"][i,2]))
+ fp.close()
+
diff -r 70f267d2671fa4734f4c48d9eda3ead5c615020e -r f6cc8e9297e8b0a4250d5d975f8f0abf9ce62fcc yt/visualization/volume_rendering/create_spline.py
--- /dev/null
+++ b/yt/visualization/volume_rendering/create_spline.py
@@ -0,0 +1,75 @@
+"""
+Create a Catmull-Rom spline.
+
+Author: John Wise <jwise at physics.gatech.edu>
+Affiliation: Georgia Tech
+Homepage: http://yt-project.org/
+License:
+ Copyright (C) 2012 John Wise. All Rights Reserved.
+
+ This file is part of yt.
+
+ yt is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import numpy as na
+
+def create_spline(old_x, old_y, new_x, tension=0.5, sorted=False):
+ """
+Inputs:
+ old_x: array of floats
+ Original x-data to be fit with a Catmull-Rom spline
+ old_y: array of floats
+ Original y-data to be fit with a Catmull-Rom spline
+ new_x: array of floats
+ interpolate to these x-coordinates
+ tension: float, optional
+ controls the tension at the specified coordinates
+ sorted: boolean, optional
+ If True, then the old_x and old_y arrays are sorted, and then this routine
+ does not try to sort the coordinates
+Outputs:
+ result: array of floats
+ interpolated y-coordinates
+ """
+ ndata = len(old_x)
+ N = len(new_x)
+ result = na.zeros(N)
+ if not sorted:
+ isort = na.argsort(old_x)
+ old_x = old_x[isort]
+ old_y = old_y[isort]
+ # Floor/ceiling of values outside of the original data
+ new_x = na.minimum(new_x, old_x[-1])
+ new_x = na.maximum(new_x, old_x[0])
+ ind = na.searchsorted(old_x, new_x)
+ im2 = na.maximum(ind-2, 0)
+ im1 = na.maximum(ind-1, 0)
+ ip1 = na.minimum(ind+1, ndata-1)
+ for i in range(N):
+ if ind[i] != im1[i]:
+ u = (new_x[i] - old_x[im1[i]]) / (old_x[ind[i]] - old_x[im1[i]])
+ elif ind[i] == im1[i]:
+ u = 0
+ else:
+ print "Bad index during interpolation?"
+ sys.exit()
+ b0 = -tension * u + 2*tension * u**2 - tension * u**3
+ b1 = 1.0 + (tension-3) * u**2 + (2-tension) * u**3
+ b2 = tension * u + (3 - 2*tension) * u**2 + (tension-2) * u**3
+ b3 = -tension * u**2 + tension * u**3
+ result[i] = b0 * old_y[im2[i]] + b1 * old_y[im1[i]] + \
+ b2 * old_y[ind[i]] + b3 * old_y[ip1[i]]
+ return result
+
Repository URL: https://bitbucket.org/yt_analysis/yt/
--
This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.
More information about the yt-svn
mailing list