def _get_projective_endpoints_of_line(vertices, vertex_reflections): e = PrimitivesDistanceEngine([0,0], vertex_reflections) endpoints, h = e.fixed_projective_points_or_bounding_halfsphere() if not endpoints: raise Exception("Blah") CIF = vertices[0].z.parent() for i in range(1, 4): m = _adjoint2( ProjectivePoint.matrix_taking_0_1_inf_to_given_points( endpoints[0], ProjectivePoint(CIF(i)), endpoints[1])) if m.det().abs() > 0: try: vs = [ v.translate_PGL(m) for v in vertices ] except: continue if not all([not v.z != 0 for v in vs]): raise Exception("Images of vertices supposed to be " "on vertical line.") if vs[0].t > vs[1].t: return endpoints[::-1] if vs[0].t < vs[1].t: return endpoints raise Exception("Could not find endpoints")
def _rotation_helper(z0, z1, r): CIF = z0.z.parent() m1 = matrix([[z.get_numerator() for z in [z0, z1]], [z.get_denominator() for z in [z0, z1]]]) m2 = matrix(CIF, [[r, 0], [0, 1]]) return m1 * m2 * _adjoint2(m1)
def _compute_transform_taking_face_to_0_1_inf(tet, f, CIF): projectivePoints = [ ProjectivePoint.fromComplexIntervalFieldAndIdealPoint( CIF, tet.Class[v].IdealPoint) for v in simplex.ZeroSubsimplices if v & f ] m = ProjectivePoint.matrix_taking_0_1_inf_to_given_points(*projectivePoints) return _adjoint2(m / sqrt(m.det()))
def compute_inradius_and_incenter(projectivePoints): """ Radius and center of an inscribed sphere of an ideal tetrahedron. The function expects four :class:`ProjectivePoint` and returns a pair of a ``RealIntervalField`` element and a :class:`FinitePoint`:: sage: from sage.all import * sage: z0 = ProjectivePoint(CIF(0), inverted = True) sage: z1 = ProjectivePoint(CIF(0)) sage: z2 = ProjectivePoint(CIF(0, RIF(3.4142, 3.4143))) sage: z3 = ProjectivePoint(CIF(RIF(3.4142, 3.4143), 0)) sage: ProjectivePoint.compute_inradius_and_incenter([z0, z1, z2, z3]) # doctest: +NUMERIC12 (0.317?, FinitePoint(1.0000? + 1.0000?*I, 3.108?)) """ # We assume that one of the points is at infinity. if not len(projectivePoints) == 4: raise Exception("Expecting 4 ProjectivePoint's") pointClosestToInf = -1 distToInf = sage.all.Infinity for i, projectivePoint in enumerate(projectivePoints): if projectivePoint.inverted: d = abs(projectivePoint.z).upper() if d < distToInf: pointClosestToInf = i distToInf = d if pointClosestToInf == -1: return compute_inradius_and_incenter( [ projectivePoint.as_ideal_point() for projectivePoint in projectivePoints ]) zInv = projectivePoints[pointClosestToInf].z CIF = zInv.parent() gl_matrix = matrix(CIF, [[ 1, 0], [-zInv, 1]]) sl_matrix = CIF(sage.all.I) * gl_matrix inv_sl_matrix = _adjoint2(sl_matrix) transformedIdealPoints = [ p.translate(gl_matrix).as_ideal_point() for i, p in enumerate(projectivePoints) if i != pointClosestToInf ] inradius, transformedInCenter = ( _compute_inradius_and_incenter_with_one_point_at_infinity( transformedIdealPoints)) return inradius, transformedInCenter.translate_PSL(inv_sl_matrix)
def _get_matrix_to_std_form(self): """ Compute the matrix bringing the triangle into the plane with imaginary part 0. For an ideal triangle, the matrix will bring the vertices to 0, 1, and infinity. """ if self._matrix_to_std_form is None: self._matrix_to_std_form = _adjoint2( ProjectivePoint.matrix_taking_0_1_inf_to_given_points( *self.three_projective_endpoints)) return self._matrix_to_std_form
def compute_incenter_of_triangle(projectivePoints): """ Computes incenter of an ideal triangle. The function expects three :class:`ProjectivePoint` and returns a :class:`FinitePoint`:: sage: from sage.all import * sage: z0 = ProjectivePoint(CIF(0), inverted = True) sage: z1 = ProjectivePoint(CIF(0)) sage: z2 = ProjectivePoint(CIF(1)) sage: ProjectivePoint.compute_incenter_of_triangle([z0, z1, z2]) FinitePoint(0.50000000000000000?, 0.866025403784439?) """ if not len(projectivePoints) == 3: raise ValueError("Expecting 3 ProjectivePoint's") pointClosestToInf = -1 distToInf = sage.all.Infinity for i, projectivePoint in enumerate(projectivePoints): if projectivePoint.inverted: d = abs(projectivePoint.z).upper() if d < distToInf: pointClosestToInf = i distToInf = d if pointClosestToInf == -1: return compute_incenter_of_triangle( [ projectivePoint.as_ideal_point() for projectivePoint in projectivePoints ]) zInv = projectivePoints[pointClosestToInf].z CIF = zInv.parent() gl_matrix = matrix(CIF, [[ 1, 0], [-zInv, 1]]) sl_matrix = CIF(sage.all.I) * gl_matrix inv_sl_matrix = _adjoint2(sl_matrix) transformedIdealPoints = [ p.translate(gl_matrix).as_ideal_point() for i, p in enumerate(projectivePoints) if i != pointClosestToInf ] transformedInCenter = ( _compute_incenter_of_triangle_with_one_point_at_infinity( transformedIdealPoints)) return transformedInCenter.translate_PSL(inv_sl_matrix)
def needs_to_be_added(self, m): minv = _adjoint2(m) for tet in self.mcomplex.Tetrahedra: for f in simplex.TwoSubsimplices: if not tet.Neighbor[f]: mt = tet.transform_taking_face_to_0_1_inf[f] * minv for tet1 in self.mcomplex.Tetrahedra: if not has_distance_larger( tet1.InCenter.translate_PSL(mt), tet1.CutOffFactor): return True return False
def from_three_projective_points(z0, z1, z2): m = ProjectivePoint.matrix_taking_0_1_inf_to_given_points(z0, z1, z2) return ExtendedMatrix(m, True) * ExtendedMatrix(_adjoint2(m))