def correct(repeat_border_atoms = false)
      
      # Hash for storing bounding planes and the out-of-plane vector
      # by which each atom will be displaced to move it into the primitive volume
      # key = bounding plane
      # value = out-of-plane lattice vector used to displace atoms
      planes_vecs = {}

      # Define the primitive volume as six planes by 
      # finding the normal to each pair of lattice vectors
      # and making a plane with this normal that includes
      #   1. The point at the head of the third lattice vector 
      #      and pointing in the positive direction
      #
      #   2. The point at the tail of the third lattice vector
      #      and pointing in the negative direction  
      #
      (0..2).each do |i|
        out_vector = lattice_vectors[i] # The out of plane vector
        plane_vectors = lattice_vectors.reject{|v| v == out_vector} # The in plane vectors
        norm = cross(plane_vectors[0], plane_vectors[1])
        # if the norm has a component in the direction of the out of plane vector
        # then use the head of the out-of-plane vector as the intersection point
        # otherwise use the tail (the origin)
        if 0 < dot(norm, out_vector)
          # First plane is in direction of norm and intersects head
          # Displace vector is +1 if plane intersects tail and -1 if plane intersects head.
          planes_vecs[Plane.new(norm[0], norm[1], norm[2], out_vector[0], out_vector[1], out_vector[2])] = out_vector*(-1)
          # Second plane is opposite direction of norm and intersects tail
          planes_vecs[Plane.new(-norm[0], -norm[1], -norm[2], 0, 0, 0)] = out_vector*1
        else
          # First plane is in opposite direction of norm and intersects head
          planes_vecs[Plane.new(-norm[0], -norm[1], -norm[2], out_vector[0], out_vector[1], out_vector[2])] = out_vector*(-1)
          # Second plane is in direction of norm and intersects tail
          planes_vecs[Plane.new(norm[0], norm[1], norm[2], 0, 0, 0)] = out_vector*1
        end
      end

      # Make a coyp of the unit cell
      new_unit_cell = self.copy

      # atoms on the border will be repeated with
      # periodicity of lattice vectors for better rendering
      border_atoms = {}
      
      # Move each atom behind all the planes
      new_unit_cell.atoms(false).each_with_index do |atom, i|
        planes_vecs.each_pair do |p, v|
          if p.distance_to_point(0,0,0) == 0
            # If the plane intersects the origin then 
            # move atoms not on the plane (inequality)
            while p.distance_to_point(atom.x, atom.y, atom.z) > 1e-4
              atom.displace!(v[0], v[1], v[2])
            end
          else
            # Move atoms that lie on the plane if the plane doesn't intersect the origin
            while p.distance_to_point(atom.x, atom.y, atom.z) >= -1e-4
              atom.displace!(v[0], v[1], v[2])
            end
          end
          
          # This part repeats atoms on the unit cell boundaries
          # useful for drawing pictures, but these atoms are really repeats
          # Add each border that intersects the atom to a list
          if p.distance_to_point(atom.x, atom.y, atom.z) == 0
            if border_atoms[atom]
              border_atoms[atom] << v
            else
              border_atoms[atom] = [v]
            end
          end
        end
      end

      

      # Add more border atoms for each combination of lattice planes
      if repeat_border_atoms
        border_atoms.each_pair{|atom, planes|
          planes.size.times{|i|
            combos = Volume.choose(planes, i+1)
            combos.each{|combo|
              x = combo.inject(0){|sum, v| sum = sum + v[0]}
              y = combo.inject(0){|sum, v| sum = sum + v[1]}
              z = combo.inject(0){|sum, v| sum = sum + v[2]}
              puts [x,y,z]
              new_unit_cell.atoms(:allAtoms) << atom.displace(x, y, z)
            }
          }
        }
      end
      new_unit_cell.atoms.uniq!
      # new_unit_cell.make_bonds
      return new_unit_cell

    end
def correct(repeat_border_atoms = false)
      
      # Hash for storing bounding planes and the out-of-plane vector
      # by which each atom will be displaced to move it into the primitive volume
      # key = bounding plane
      # value = out-of-plane lattice vector used to displace atoms
      planes_vecs = {}

      # Define the primitive volume as six planes by 
      # finding the normal to each pair of lattice vectors
      # and making a plane with this normal that includes
      #   1. The point at the head of the third lattice vector 
      #      and pointing in the positive direction
      #
      #   2. The point at the tail of the third lattice vector
      #      and pointing in the negative direction  
      #
      (0..2).each do |i|
        out_vector = lattice_vectors[i] # The out of plane vector
        plane_vectors = lattice_vectors.reject{|v| v == out_vector} # The in plane vectors
        norm = cross(plane_vectors[0], plane_vectors[1])
        # if the norm has a component in the direction of the out of plane vector
        # then use the head of the out-of-plane vector as the intersection point
        # otherwise use the tail (the origin)
        if 0 < dot(norm, out_vector)
          # First plane is in direction of norm and intersects head
          # Displace vector is +1 if plane intersects tail and -1 if plane intersects head.
          planes_vecs[Plane.new(norm[0], norm[1], norm[2], out_vector[0], out_vector[1], out_vector[2])] = out_vector*(-1)
          # Second plane is opposite direction of norm and intersects tail
          planes_vecs[Plane.new(-norm[0], -norm[1], -norm[2], 0, 0, 0)] = out_vector*1
        else
          # First plane is in opposite direction of norm and intersects head
          planes_vecs[Plane.new(-norm[0], -norm[1], -norm[2], out_vector[0], out_vector[1], out_vector[2])] = out_vector*(-1)
          # Second plane is in direction of norm and intersects tail
          planes_vecs[Plane.new(norm[0], norm[1], norm[2], 0, 0, 0)] = out_vector*1
        end
      end

      # Make a coyp of the unit cell
      new_unit_cell = self.copy

      # atoms on the border will be repeated with
      # periodicity of lattice vectors for better rendering
      border_atoms = {}
      
      # Move each atom behind all the planes
      new_unit_cell.atoms(false).each_with_index do |atom, i|
        planes_vecs.each_pair do |p, v|
          if p.distance_to_point(0,0,0) == 0
            # If the plane intersects the origin then 
            # move atoms not on the plane (inequality)
            while p.distance_to_point(atom.x, atom.y, atom.z) > 1e-4
              atom.displace!(v[0], v[1], v[2])
            end
          else
            # Move atoms that lie on the plane if the plane doesn't intersect the origin
            while p.distance_to_point(atom.x, atom.y, atom.z) >= -1e-4
              atom.displace!(v[0], v[1], v[2])
            end
          end
          
          # This part repeats atoms on the unit cell boundaries
          # useful for drawing pictures, but these atoms are really repeats
          # Add each border that intersects the atom to a list
          if p.distance_to_point(atom.x, atom.y, atom.z) == 0
            if border_atoms[atom]
              border_atoms[atom] << v
            else
              border_atoms[atom] = [v]
            end
          end
        end
      end

      

      # Add more border atoms for each combination of lattice planes
      if repeat_border_atoms
        border_atoms.each_pair{|atom, planes|
          planes.size.times{|i|
            combos = Volume.choose(planes, i+1)
            combos.each{|combo|
              x = combo.inject(0){|sum, v| sum = sum + v[0]}
              y = combo.inject(0){|sum, v| sum = sum + v[1]}
              z = combo.inject(0){|sum, v| sum = sum + v[2]}
              puts [x,y,z]
              new_unit_cell.atoms(:allAtoms) << atom.displace(x, y, z)
            }
          }
        }
      end
      new_unit_cell.atoms.uniq!
      # new_unit_cell.make_bonds
      return new_unit_cell

    end
Move all atoms inside the primitive volume defined by the
 six planes of the lattice vectors