def __init__(self, projection_direction, height=1.1): """ Initializes the projection. EXAMPLES:: sage: from sage.geometry.polyhedron.plot import ProjectionFuncSchlegel sage: proj = ProjectionFuncSchlegel([2,2,2]) sage: proj.__init__([2,2,2]) sage: proj(vector([1.1,1.1,1.11]))[0] 0.0302... sage: TestSuite(proj).run(skip='_test_pickling') """ self.projection_dir = vector(RDF, projection_direction) if norm(self.projection_dir).is_zero(): raise ValueError, "projection direction must be a non-zero vector." self.dim = self.projection_dir.degree() spcenter = height * self.projection_dir / norm(self.projection_dir) self.height = height v = vector(RDF, [0.0] * (self.dim - 1) + [self.height]) - spcenter polediff = matrix(RDF, v).transpose() denom = (polediff.transpose() * polediff)[0][0] if denom.is_zero(): self.house = identity_matrix(RDF, self.dim) else: self.house = identity_matrix(RDF,self.dim) \ - 2*polediff*polediff.transpose()/denom #Householder reflector
def __init__(self, projection_direction, height = 1.1): """ Initializes the projection. EXAMPLES:: sage: from sage.geometry.polyhedron.plot import ProjectionFuncSchlegel sage: proj = ProjectionFuncSchlegel([2,2,2]) sage: proj.__init__([2,2,2]) sage: proj(vector([1.1,1.1,1.11]))[0] 0.0302... sage: TestSuite(proj).run(skip='_test_pickling') """ self.projection_dir = vector(RDF, projection_direction) if norm(self.projection_dir).is_zero(): raise ValueError, "projection direction must be a non-zero vector." self.dim = self.projection_dir.degree() spcenter = height * self.projection_dir/norm(self.projection_dir) self.height = height v = vector(RDF, [0.0]*(self.dim-1) + [self.height]) - spcenter polediff = matrix(RDF,v).transpose() denom = (polediff.transpose()*polediff)[0][0] if denom.is_zero(): self.house = identity_matrix(RDF,self.dim) else: self.house = identity_matrix(RDF,self.dim) \ - 2*polediff*polediff.transpose()/denom #Householder reflector
def _normalize(x): r""" make x of length 1 """ from sage.misc.functional import norm x=vector(RR, x) if norm(x) == 0: return x return vector(x/norm(x))
def _normalize(x): r""" make x of length 1 """ from sage.misc.functional import norm x = vector(x) if norm(x) == 0: return x return vector(x / norm(x))
def orthonormal_1(dim_n=5): """ A matrix of rational approximations to orthonormal vectors to ``(1,...,1)``. INPUT: - ``dim_n`` - the dimension of the vectors OUTPUT: A matrix over ``QQ`` whose rows are close to an orthonormal basis to the subspace normal to ``(1,...,1)``. EXAMPLES:: sage: from sage.geometry.polyhedron.library import Polytopes sage: m = Polytopes.orthonormal_1(5) sage: m [ 70711/100000 -7071/10000 0 0 0] [ 1633/4000 1633/4000 -81649/100000 0 0] [ 7217/25000 7217/25000 7217/25000 -43301/50000 0] [ 22361/100000 22361/100000 22361/100000 22361/100000 -44721/50000] """ pb = [] for i in range(0,dim_n-1): pb.append([1.0/(i+1)]*(i+1) + [-1] + [0]*(dim_n-i-2)) m = matrix(RDF,pb) new_m = [] for i in range(0,dim_n-1): new_m.append([RDF(100000*q/norm(m[i])).ceil()/100000 for q in m[i]]) return matrix(QQ,new_m)
def _arc(p,q,s,**kwds): #rewrite this to use polar_plot and get points to do filled triangles from sage.misc.functional import det from sage.plot.line import line from sage.misc.functional import norm from sage.symbolic.all import pi from sage.plot.arc import arc p,q,s = map( lambda x: vector(x), [p,q,s]) # to avoid running into division by 0 we set to be colinear vectors that are # almost colinear if abs(det(matrix([p-s,q-s])))<0.01: return line((p,q),**kwds) (cx,cy)=var('cx','cy') equations=[ 2*cx*(s[0]-p[0])+2*cy*(s[1]-p[1]) == s[0]**2+s[1]**2-p[0]**2-p[1]**2, 2*cx*(s[0]-q[0])+2*cy*(s[1]-q[1]) == s[0]**2+s[1]**2-q[0]**2-q[1]**2 ] c = vector( [solve( equations, (cx,cy), solution_dict=True )[0][i] for i in [cx,cy]] ) r = norm(p-c) a_p,a_q,a_s = map( _to_angle, [p-c,q-c,s-c]) angles = [a_p,a_q,a_s] angles.sort() if a_s == angles[0]: return arc( c, r, angle=angles[2], sector=(0,2*pi-angles[2]+angles[1]), **kwds) if a_s == angles[1]: return arc( c, r, angle=angles[0], sector=(0,angles[2]-angles[0]), **kwds) if a_s == angles[2]: return arc( c, r, angle=angles[1], sector=(0,2*pi-angles[1]+angles[0]), **kwds)
def __init__(self, projection_point): """ Create a stereographic projection function. INPUT: - ``projection_point`` -- a list of coordinates in the appropriate dimension, which is the point projected from. EXAMPLES:: sage: from sage.geometry.polyhedron.plot import ProjectionFuncStereographic sage: proj = ProjectionFuncStereographic([1.0,1.0]) sage: proj.__init__([1.0,1.0]) sage: proj.house [-0.7071067811... 0.7071067811...] [ 0.7071067811... 0.7071067811...] sage: TestSuite(proj).run(skip='_test_pickling') """ self.projection_point = vector(projection_point) self.dim = self.projection_point.degree() pproj = vector(RDF, self.projection_point) self.psize = norm(pproj) if (self.psize).is_zero(): raise ValueError, "projection direction must be a non-zero vector." v = vector(RDF, [0.0] * (self.dim - 1) + [self.psize]) - pproj polediff = matrix(RDF, v).transpose() denom = RDF((polediff.transpose() * polediff)[0][0]) if denom.is_zero(): self.house = identity_matrix(RDF, self.dim) else: self.house = identity_matrix(RDF,self.dim) \ - 2*polediff*polediff.transpose()/denom # Householder reflector
def orthonormal_1(dim_n=5): """ A matrix of rational approximations to orthonormal vectors to ``(1,...,1)``. INPUT: - ``dim_n`` - the dimension of the vectors OUTPUT: A matrix over ``QQ`` whose rows are close to an orthonormal basis to the subspace normal to ``(1,...,1)``. EXAMPLES:: sage: from sage.geometry.polyhedron.library import Polytopes sage: m = Polytopes.orthonormal_1(5) sage: m [ 70711/100000 -7071/10000 0 0 0] [ 1633/4000 1633/4000 -81649/100000 0 0] [ 7217/25000 7217/25000 7217/25000 -43301/50000 0] [ 22361/100000 22361/100000 22361/100000 22361/100000 -44721/50000] """ pb = [] for i in range(0, dim_n - 1): pb.append([1.0 / (i + 1)] * (i + 1) + [-1] + [0] * (dim_n - i - 2)) m = matrix(RDF, pb) new_m = [] for i in range(0, dim_n - 1): new_m.append( [RDF(100000 * q / norm(m[i])).ceil() / 100000 for q in m[i]]) return matrix(QQ, new_m)
def __init__(self, projection_point): """ Create a stereographic projection function. INPUT: - ``projection_point`` -- a list of coordinates in the appropriate dimension, which is the point projected from. EXAMPLES:: sage: from sage.geometry.polyhedron.plot import ProjectionFuncStereographic sage: proj = ProjectionFuncStereographic([1.0,1.0]) sage: proj.__init__([1.0,1.0]) sage: proj.house [-0.7071067811... 0.7071067811...] [ 0.7071067811... 0.7071067811...] sage: TestSuite(proj).run(skip='_test_pickling') """ self.projection_point = vector(projection_point) self.dim = self.projection_point.degree() pproj = vector(RDF,self.projection_point) self.psize = norm(pproj) if (self.psize).is_zero(): raise ValueError, "projection direction must be a non-zero vector." v = vector(RDF, [0.0]*(self.dim-1) + [self.psize]) - pproj polediff = matrix(RDF,v).transpose() denom = RDF((polediff.transpose()*polediff)[0][0]) if denom.is_zero(): self.house = identity_matrix(RDF,self.dim) else: self.house = identity_matrix(RDF,self.dim) \ - 2*polediff*polediff.transpose()/denom # Householder reflector
def _arc(p, q, s, **kwds): #rewrite this to use polar_plot and get points to do filled triangles from sage.misc.functional import det from sage.plot.line import line from sage.misc.functional import norm from sage.symbolic.all import pi from sage.plot.arc import arc p, q, s = map(lambda x: vector(x), [p, q, s]) # to avoid running into division by 0 we set to be colinear vectors that are # almost colinear if abs(det(matrix([p - s, q - s]))) < 0.01: return line((p, q), **kwds) (cx, cy) = var('cx', 'cy') equations = [ 2 * cx * (s[0] - p[0]) + 2 * cy * (s[1] - p[1]) == s[0]**2 + s[1]**2 - p[0]**2 - p[1]**2, 2 * cx * (s[0] - q[0]) + 2 * cy * (s[1] - q[1]) == s[0]**2 + s[1]**2 - q[0]**2 - q[1]**2 ] c = vector([ solve(equations, (cx, cy), solution_dict=True)[0][i] for i in [cx, cy] ]) r = norm(p - c) a_p, a_q, a_s = map(lambda x: atan2(x[1], x[0]), [p - c, q - c, s - c]) a_p, a_q = sorted([a_p, a_q]) if a_s < a_p or a_s > a_q: return arc(c, r, angle=a_q, sector=(0, 2 * pi - a_q + a_p), **kwds) return arc(c, r, angle=a_p, sector=(0, a_q - a_p), **kwds)
def _stereo_coordinates(x, north=(1,0,0), right=(0,1,0), translation=-1): r""" Project stereographically points from a sphere """ from sage.misc.functional import norm north=_normalize(north) right=vector(right) right=_normalize(right-(right*north)*north) if norm(right) == 0: raise ValueError ("Right must not be linearly dependent from north") top=north.cross_product(right) x=_normalize(x) p=(translation-north*x)/(1-north*x)*(north-x)+x return vector((right*p, top*p ))
def _stereo_coordinates(x, north=(1, 0, 0), right=(0, 1, 0), translation=-1): r""" Project stereographically points from a sphere """ from sage.misc.functional import norm north = _normalize(north) right = vector(right) right = _normalize(right - (right * north) * north) if norm(right) == 0: raise ValueError("Right must not be linearly dependent from north") top = north.cross_product(right) x = _normalize(x) p = (translation - north * x) / (1 - north * x) * (north - x) + x return vector((right * p, top * p))
def __call__(self, x): """ Apply the projection to a vector. - ``x`` -- a vector or anything convertible to a vector. EXAMPLES:: sage: from sage.geometry.polyhedron.plot import ProjectionFuncSchlegel sage: proj = ProjectionFuncSchlegel([2,2,2]) sage: proj.__call__([1,2,3]) (0.56162854..., 2.09602626...) """ v = vector(RDF, x) if v.is_zero(): raise ValueError, "The origin must not be a vertex." v = v / norm(v) # normalize vertices to unit sphere v = self.house * v # reflect so self.projection_dir is at "north pole" denom = self.height - v[self.dim - 1] if denom.is_zero(): raise ValueError, 'Point cannot coincide with ' \ 'coordinate singularity at ' + repr(x) return vector(RDF, [v[i] / denom for i in range(self.dim - 1)])
def __call__(self, x): """ Apply the projection to a vector. - ``x`` -- a vector or anything convertible to a vector. EXAMPLES:: sage: from sage.geometry.polyhedron.plot import ProjectionFuncSchlegel sage: proj = ProjectionFuncSchlegel([2,2,2]) sage: proj.__call__([1,2,3]) (0.56162854..., 2.09602626...) """ v = vector(RDF,x) if v.is_zero(): raise ValueError, "The origin must not be a vertex." v = v/norm(v) # normalize vertices to unit sphere v = self.house*v # reflect so self.projection_dir is at "north pole" denom = self.height-v[self.dim-1] if denom.is_zero(): raise ValueError, 'Point cannot coincide with ' \ 'coordinate singularity at ' + repr(x) return vector(RDF, [ v[i]/denom for i in range(self.dim-1) ])
# FIXME: refactor this before publishing r""" Usese parametric_plot3d() to plot arcs of a circle. We only plot arcs spanning algles strictly less than pi. """ # For sanity purposes convert the input to vectors from sage.misc.functional import norm from sage.modules.free_module_element import vector from sage.functions.trig import arccos, cos, sin from sage.plot.plot3d.parametric_plot3d import parametric_plot3d center=vector(center) first_point=vector(first_point) second_point=vector(second_point) first_vector=first_point-center second_vector=second_point-center radius=norm(first_vector) if norm(second_vector)!=radius: raise ValueError("Ellipse not implemented") first_unit_vector=first_vector/radius second_unit_vector=second_vector/radius normal_vector=second_vector-(second_vector*first_unit_vector)*first_unit_vector if norm(normal_vector)==0: print (first_point,second_point) return normal_unit_vector=normal_vector/norm(normal_vector) scalar_product=first_unit_vector*second_unit_vector if abs(scalar_product) == 1: raise ValueError("The points are alligned") angle=arccos(scalar_product) var('t') return parametric_plot3d(center+first_vector*cos(t)+radius*normal_unit_vector*sin(t),(0,angle),**kwds)
# FIXME: refactor this before publishing r""" Usese parametric_plot3d() to plot arcs of a circle. We only plot arcs spanning algles strictly less than pi. """ # For sanity purposes convert the input to vectors from sage.misc.functional import norm from sage.modules.free_module_element import vector from sage.functions.trig import arccos, cos, sin from sage.plot.plot3d.parametric_plot3d import parametric_plot3d center = vector(center) first_point = vector(first_point) second_point = vector(second_point) first_vector = first_point - center second_vector = second_point - center radius = norm(first_vector) if norm(second_vector) != radius: raise ValueError("Ellipse not implemented") first_unit_vector = first_vector / radius second_unit_vector = second_vector / radius normal_vector = second_vector - (second_vector * first_unit_vector) * first_unit_vector if norm(normal_vector) == 0: print(first_point, second_point) return normal_unit_vector = normal_vector / norm(normal_vector) scalar_product = first_unit_vector * second_unit_vector if abs(scalar_product) == 1: raise ValueError("The points are alligned") angle = arccos(scalar_product) var('t')