diff --git a/mrdna/segmentmodel.py b/mrdna/segmentmodel.py
index ff074d94923ad9c4b860ba24f440f778c02211ea..74f5780b2161fd4b263fa7e90bf20c404f29fe13 100644
--- a/mrdna/segmentmodel.py
+++ b/mrdna/segmentmodel.py
@@ -453,6 +453,16 @@ class Segment(ConnectableElement, Group):
         tck, u = self.position_spline_params
         return np.mean(self.contour_to_position(u), axis=0)
 
+    def get_bounding_box( self, num_points=3 ):
+        positions = np.zeros( num_points, 3)
+        i = 0
+        for c in linspace(0,1,num_points):
+            positions[i] = self.contour_to_position(c)
+            i += 1
+        min_ = np.array([np.min(positions[:,i]) for i in range(3)])
+        max_ = np.array([np.max(positions[:,i]) for i in range(3)])
+        return min_,max_
+
     def _get_location_positions(self):
         return [self.contour_to_nt_pos(l.address) for l in self.locations]
 
@@ -558,7 +568,7 @@ class Segment(ConnectableElement, Group):
         if self.quaternion_spline_params is not None:
             ## TODO: performance: don't shift between quaternion and matrix representations so much
             tck, u = self.quaternion_spline_params
-            orientations = [self.contour_to_orientation(v) for v in u]
+            orientations = np.array([self.contour_to_orientation(v) for v in u])
             for i in ids:
                 orientations[i,:] = rotation_matrix.dot(orientations[i])
             quats = [quaternion_from_matrix(o) for o in orientations]
@@ -3215,17 +3225,27 @@ proc calcforces {} {
 }
 """)
 
-    def dimensions_from_structure( self, padding_factor=1.5, isotropic=False ):
-        positions = []
+    def get_bounding_box( self, num_points=3 ):
+        positions = np.zeros( (len(self.segments)*num_points, 3) )
+        i = 0
         for s in self.segments:
-            positions.append(s.contour_to_position(0))
-            positions.append(s.contour_to_position(0.5))
-            positions.append(s.contour_to_position(1))
-        positions = np.array(positions)
-        dx,dy,dz = [(np.max(positions[:,i])-np.min(positions[:,i])+30)*padding_factor for i in range(3)]
+            for c in linspace(0,1,num_points):
+                positions[i] = (s.contour_to_position(c))
+                i += 1
+        min_ = np.array([np.min(positions[:,i]) for i in range(3)])
+        max_ = np.array([np.max(positions[:,i]) for i in range(3)])
+        return min_,max_
+
+    def get_bounding_box_center( self, num_points=3 ):
+        min_,max_ = self.get_bounding_box(num_points)
+        return 0.5*(max_+min_)
+
+    def dimensions_from_structure( self, padding_factor=1.5, isotropic=False ):
+        min_,max_ = self.get_bounding_box()
+        dx,dy,dz = (max_-min_+30)*padding_factor
         if isotropic:
             dx = dy = dz = max((dx,dy,dz))
-        return [dx,dy,dz]
+        return np.array([dx,dy,dz])
 
     def add_grid_potential(self, grid_file, scale=1, per_nucleotide=True):
         grid_file = Path(grid_file)