| 1032 | |
| 1033 | def tikz(self, view=[0,0,1], angle=0, scale=2, |
| 1034 | edge_color='blue!95!black', facet_color='blue!95!black', |
| 1035 | opacity=0.8, vertex_color='green', axis=False): |
| 1036 | r""" |
| 1037 | Return a string ``tikz_pic`` consisting of a tikz picture of ``self`` |
| 1038 | according to a projection ``view`` and an angle ``angle`` |
| 1039 | obtained via Jmol through the current state property. |
| 1040 | |
| 1041 | INPUT: |
| 1042 | |
| 1043 | - ``view`` - list (default: [0,0,1]) representing the rotation axis (see note below). |
| 1044 | - ``angle`` - integer (default: 0) angle of rotation in degree from 0 to 360 (see note |
| 1045 | below). |
| 1046 | - ``scale`` - integer (default: 2) specifying the scaling of the tikz picture. |
| 1047 | - ``edge_color`` - string (default: 'blue!95!black') representing colors which tikz |
| 1048 | recognize. |
| 1049 | - ``facet_color`` - string (default: 'blue!95!black') representing colors which tikz |
| 1050 | recognize. |
| 1051 | - ``vertex_color`` - string (default: 'green') representing colors which tikz |
| 1052 | recognize. |
| 1053 | - ``opacity`` - real number (default: 0.8) between 0 and 1 giving the opacity of |
| 1054 | the front facets. |
| 1055 | - ``axis`` - Boolean (default: False) draw the axes at the origin or not. |
| 1056 | |
| 1057 | OUTPUT: |
| 1058 | |
| 1059 | - LatexExpr -- containing the TikZ picture. |
| 1060 | |
| 1061 | .. NOTE:: |
| 1062 | |
| 1063 | The inputs ``view`` and ``angle`` can be obtained from the |
| 1064 | viewer Jmol:: |
| 1065 | |
| 1066 | 1) Right click on the image |
| 1067 | 2) Select ``Console`` |
| 1068 | 3) Select the tab ``State`` |
| 1069 | 4) Scroll to the line ``moveto`` |
| 1070 | |
| 1071 | It reads something like:: |
| 1072 | |
| 1073 | moveto 0.0 {x y z angle} Scale |
| 1074 | |
| 1075 | The ``view`` is then [x,y,z] and ``angle`` is angle. |
| 1076 | The following number is the scale. |
| 1077 | |
| 1078 | Jmol performs a rotation of ``angle`` degrees along the |
| 1079 | vector [x,y,z] and show the result from the z-axis. |
| 1080 | |
| 1081 | EXAMPLES:: |
| 1082 | |
| 1083 | sage: P1 = polytopes.small_rhombicuboctahedron() |
| 1084 | sage: Image1 = P1.projection().tikz([1,3,5], 175, scale=4) |
| 1085 | sage: type(Image1) |
| 1086 | <class 'sage.misc.latex.LatexExpr'> |
| 1087 | sage: print '\n'.join(Image1.splitlines()[:4]) |
| 1088 | \begin{tikzpicture}% |
| 1089 | [x={(-0.939161cm, 0.244762cm)}, |
| 1090 | y={(0.097442cm, -0.482887cm)}, |
| 1091 | z={(0.329367cm, 0.840780cm)}, |
| 1092 | sage: open('polytope-tikz1.tex', 'w').write(Image1) # not tested |
| 1093 | |
| 1094 | sage: P2 = Polyhedron(vertices=[[1, 1],[1, 2],[2, 1]]) |
| 1095 | sage: Image2 = P2.projection().tikz(scale=3, edge_color='blue!95!black', facet_color='orange!95!black', opacity=0.4, vertex_color='yellow', axis=True) |
| 1096 | sage: type(Image2) |
| 1097 | <class 'sage.misc.latex.LatexExpr'> |
| 1098 | sage: print '\n'.join(Image2.splitlines()[:4]) |
| 1099 | \begin{tikzpicture}% |
| 1100 | [scale=3.000000, |
| 1101 | back/.style={loosely dotted, thin}, |
| 1102 | edge/.style={color=blue!95!black, thick}, |
| 1103 | sage: open('polytope-tikz2.tex', 'w').write(Image2) # not tested |
| 1104 | |
| 1105 | sage: P3 = Polyhedron(vertices=[[-1, -1, 2],[-1, 2, -1],[2, -1, -1]]) |
| 1106 | sage: P3 |
| 1107 | A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices |
| 1108 | sage: Image3 = P3.projection().tikz([0.5,-1,-0.1], 55, scale=3, edge_color='blue!95!black',facet_color='orange!95!black', opacity=0.7, vertex_color='yellow', axis=True) |
| 1109 | sage: print '\n'.join(Image3.splitlines()[:4]) |
| 1110 | \begin{tikzpicture}% |
| 1111 | [x={(0.658184cm, -0.242192cm)}, |
| 1112 | y={(-0.096240cm, 0.912008cm)}, |
| 1113 | z={(-0.746680cm, -0.331036cm)}, |
| 1114 | sage: open('polytope-tikz3.tex', 'w').write(Image3) # not tested |
| 1115 | |
| 1116 | sage: P=Polyhedron(vertices=[[1,1,0,0],[1,2,0,0],[2,1,0,0],[0,0,1,0],[0,0,0,1]]) |
| 1117 | sage: P |
| 1118 | A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices |
| 1119 | sage: P.projection().tikz() |
| 1120 | Traceback (most recent call last): |
| 1121 | ... |
| 1122 | NotImplementedError: The polytope has to live in 2 or 3 dimensions. |
| 1123 | |
| 1124 | .. TODO:: |
| 1125 | |
| 1126 | Make it possible to draw Schlegel diagram for 4-polytopes. :: |
| 1127 | |
| 1128 | sage: P=Polyhedron(vertices=[[1,1,0,0],[1,2,0,0],[2,1,0,0],[0,0,1,0],[0,0,0,1]]) |
| 1129 | sage: P |
| 1130 | A 4-dimensional polyhedron in ZZ^4 defined as the convex hull of 5 vertices |
| 1131 | sage: P.projection().tikz() |
| 1132 | Traceback (most recent call last): |
| 1133 | ... |
| 1134 | NotImplementedError: The polytope has to live in 2 or 3 dimensions. |
| 1135 | |
| 1136 | Make it possible to draw 3-polytopes living in higher dimension. |
| 1137 | """ |
| 1138 | if self.polyhedron_ambient_dim > 3 or self.polyhedron_ambient_dim < 2: |
| 1139 | raise NotImplementedError("The polytope has to live in 2 or 3 dimensions.") |
| 1140 | elif self.polyhedron_ambient_dim == 2: |
| 1141 | return self._tikz_2d(scale, edge_color, facet_color, opacity, |
| 1142 | vertex_color, axis) |
| 1143 | elif self.dimension == 2: |
| 1144 | return self._tikz_2d_in_3d(view, angle, scale, edge_color, |
| 1145 | facet_color, opacity, vertex_color, axis) |
| 1146 | else: |
| 1147 | return self._tikz_3d_in_3d(view, angle, scale, edge_color, |
| 1148 | facet_color, opacity, vertex_color, axis) |
| 1149 | |
| 1150 | def _tikz_2d(self, scale, edge_color, facet_color, opacity, vertex_color, axis): |
| 1151 | r""" |
| 1152 | Return a string ``tikz_pic`` consisting of a tikz picture of ``self`` |
| 1153 | |
| 1154 | INPUT: |
| 1155 | |
| 1156 | - ``scale`` - integer specifying the scaling of the tikz picture. |
| 1157 | - ``edge_color`` - string representing colors which tikz |
| 1158 | recognize. |
| 1159 | - ``facet_color`` - string representing colors which tikz |
| 1160 | recognize. |
| 1161 | - ``vertex_color`` - string representing colors which tikz |
| 1162 | recognize. |
| 1163 | - ``opacity`` - real number between 0 and 1 giving the opacity of |
| 1164 | the front facets. |
| 1165 | - ``axis`` - Boolean (default: False) draw the axes at the origin or not. |
| 1166 | |
| 1167 | OUTPUT: |
| 1168 | |
| 1169 | - LatexExpr -- containing the TikZ picture. |
| 1170 | |
| 1171 | EXAMPLES:: |
| 1172 | |
| 1173 | sage: P = Polyhedron(vertices=[[1, 1],[1, 2],[2, 1]]) |
| 1174 | sage: Image = P.projection()._tikz_2d(scale=3, edge_color='black', facet_color='orange', opacity=0.75, vertex_color='yellow', axis=True) |
| 1175 | sage: type(Image) |
| 1176 | <class 'sage.misc.latex.LatexExpr'> |
| 1177 | sage: print '\n'.join(Image.splitlines()[:4]) |
| 1178 | \begin{tikzpicture}% |
| 1179 | [scale=3.000000, |
| 1180 | back/.style={loosely dotted, thin}, |
| 1181 | edge/.style={color=black, thick}, |
| 1182 | sage: open('polytope-tikz2.tex', 'w').write(Image) # not tested |
| 1183 | |
| 1184 | .. NOTE:: |
| 1185 | |
| 1186 | The ``facet_color`` is the filing color of the polytope (polygon). |
| 1187 | """ |
| 1188 | |
| 1189 | # Creates the nodes, coordinate and tag for every vertex of the polytope. |
| 1190 | # The tag is used to draw the front facets later on. |
| 1191 | |
| 1192 | dict_drawing = {} |
| 1193 | edges = '' |
| 1194 | for vert in self.points: |
| 1195 | v = self.coords[vert] |
| 1196 | v_vect = str([i.n(digits=3) for i in v]) |
| 1197 | v_vect = v_vect.replace('[', '(') |
| 1198 | v_vect = v_vect.replace(']', ')') |
| 1199 | tag = '%s' %v_vect |
| 1200 | node = "\\node[%s] at %s {};\n" % ('vertex', tag) |
| 1201 | coord = '\coordinate %s at %s;\n' % (tag, tag) |
| 1202 | dict_drawing[vert] = node, coord, tag |
| 1203 | |
| 1204 | for index1, index2 in self.lines: |
| 1205 | # v1 = self.coords[index1] |
| 1206 | # v2 = self.coords[index2] |
| 1207 | edges += "\\draw[%s] %s -- %s;\n" % ('edge', |
| 1208 | dict_drawing[index1][2], |
| 1209 | dict_drawing[index2][2]) |
| 1210 | |
| 1211 | # Start to write the output |
| 1212 | tikz_pic = '' |
| 1213 | tikz_pic += '\\begin{tikzpicture}%\n' |
| 1214 | tikz_pic += '\t[scale=%f,\n' % scale |
| 1215 | tikz_pic += '\tback/.style={loosely dotted, thin},\n' |
| 1216 | tikz_pic += '\tedge/.style={color=%s, thick},\n' % edge_color |
| 1217 | tikz_pic += '\tfacet/.style={fill=%s,fill opacity=%f},\n' % (facet_color,opacity) |
| 1218 | tikz_pic += '\tvertex/.style={inner sep=1pt,circle,draw=%s!25!black,' % vertex_color |
| 1219 | tikz_pic += 'fill=%s!75!black,thick,anchor=base}]\n%%\n%%\n' % vertex_color |
| 1220 | |
| 1221 | # Draws the axes if True |
| 1222 | if axis: |
| 1223 | tikz_pic += '\\draw[color=black,thick,->] (0,0,0) -- (1,0,0) node[anchor=north east]{$x$};\n' |
| 1224 | tikz_pic += '\\draw[color=black,thick,->] (0,0,0) -- (0,1,0) node[anchor=north west]{$y$};\n' |
| 1225 | |
| 1226 | # Create the coordinate of the vertices: |
| 1227 | tikz_pic += '%% Coordinate of the vertices:\n%%\n' |
| 1228 | for v in dict_drawing: |
| 1229 | tikz_pic += dict_drawing[v][1] |
| 1230 | |
| 1231 | # Draw the interior by going in a cycle |
| 1232 | vertices = list(self.parent_polyhedron.Vrep_generator()) |
| 1233 | tikz_pic += '%%\n%%\n%% Drawing the interior\n%%\n' |
| 1234 | cyclic_vert = cyclic_sort_vertices_2d(list(self.parent_polyhedron.Vrep_generator())) |
| 1235 | cyclic_indices = [vertices.index(v) for v in cyclic_vert] |
| 1236 | tikz_pic += '\\fill[facet] ' |
| 1237 | for v in cyclic_indices: |
| 1238 | if v in dict_drawing: |
| 1239 | tikz_pic += '%s -- ' % dict_drawing[v][2] |
| 1240 | tikz_pic += 'cycle {};\n' |
| 1241 | |
| 1242 | # Draw the edges |
| 1243 | tikz_pic += '%%\n%%\n%% Drawing edges\n%%\n' |
| 1244 | tikz_pic += edges |
| 1245 | |
| 1246 | # Finally, the vertices in front are drawn on top of everything. |
| 1247 | tikz_pic += '%%\n%%\n%% Drawing the vertices\n%%\n' |
| 1248 | for v in dict_drawing: |
| 1249 | tikz_pic += dict_drawing[v][0] |
| 1250 | tikz_pic += '%%\n%%\n\\end{tikzpicture}' |
| 1251 | |
| 1252 | return LatexExpr(tikz_pic) |
| 1253 | |
| 1254 | def _tikz_2d_in_3d(self, view, angle, scale, edge_color, facet_color, |
| 1255 | opacity, vertex_color, axis): |
| 1256 | r""" |
| 1257 | Return a string ``tikz_pic`` consisting of a tikz picture of ``self`` |
| 1258 | according to a projection ``view`` and an angle ``angle`` |
| 1259 | obtained via Jmol through the current state property. |
| 1260 | |
| 1261 | INPUT: |
| 1262 | |
| 1263 | - ``view`` - list (default: [0,0,1]) representing the rotation axis. |
| 1264 | - ``angle`` - integer angle of rotation in degree from 0 to 360. |
| 1265 | - ``scale`` - integer specifying the scaling of the tikz picture. |
| 1266 | - ``edge_color`` - string representing colors which tikz |
| 1267 | recognize. |
| 1268 | - ``facet_color`` - string representing colors which tikz |
| 1269 | recognize. |
| 1270 | - ``vertex_color`` - string representing colors which tikz |
| 1271 | recognize. |
| 1272 | - ``opacity`` - real number between 0 and 1 giving the opacity of |
| 1273 | the front facets. |
| 1274 | - ``axis`` - Boolean draw the axes at the origin or not. |
| 1275 | |
| 1276 | OUTPUT: |
| 1277 | |
| 1278 | - LatexExpr -- containing the TikZ picture. |
| 1279 | |
| 1280 | EXAMPLE:: |
| 1281 | |
| 1282 | sage: P = Polyhedron(vertices=[[-1, -1, 2],[-1, 2, -1],[2, -1, -1]]) |
| 1283 | sage: P |
| 1284 | A 2-dimensional polyhedron in ZZ^3 defined as the convex hull of 3 vertices |
| 1285 | sage: Image = P.projection()._tikz_2d_in_3d(view=[0.5,-1,-0.5], angle=55, scale=3, edge_color='blue!95!black', facet_color='orange', opacity=0.5, vertex_color='yellow', axis=True) |
| 1286 | sage: print '\n'.join(Image.splitlines()[:4]) |
| 1287 | \begin{tikzpicture}% |
| 1288 | [x={(0.644647cm, -0.476559cm)}, |
| 1289 | y={(0.192276cm, 0.857859cm)}, |
| 1290 | z={(-0.739905cm, -0.192276cm)}, |
| 1291 | sage: open('polytope-tikz3.tex', 'w').write(Image) # not tested |
| 1292 | |
| 1293 | .. NOTE:: |
| 1294 | |
| 1295 | The ``facet_color`` is the filing color of the polytope (polygon). |
| 1296 | """ |
| 1297 | view_vector = vector(RDF, view) |
| 1298 | rot = rotate_arbitrary(view_vector,-(angle/360)*2*pi) |
| 1299 | rotation_matrix = rot[:2].transpose() |
| 1300 | |
| 1301 | # Creates the nodes, coordinate and tag for every vertex of the polytope. |
| 1302 | # The tag is used to draw the front facets later on. |
| 1303 | dict_drawing = {} |
| 1304 | edges = '' |
| 1305 | for vert in self.points: |
| 1306 | v = self.coords[vert] |
| 1307 | v_vect = str([i.n(digits=3) for i in v]) |
| 1308 | v_vect = v_vect.replace('[','(') |
| 1309 | v_vect = v_vect.replace(']',')') |
| 1310 | tag = '%s' %v_vect |
| 1311 | node = "\\node[%s] at %s {};\n" % ('vertex', tag) |
| 1312 | coord = '\coordinate %s at %s;\n' % (tag, tag) |
| 1313 | dict_drawing[vert] = node, coord, tag |
| 1314 | |
| 1315 | for index1, index2 in self.lines: |
| 1316 | # v1 = self.coords[index1] |
| 1317 | # v2 = self.coords[index2] |
| 1318 | edges += "\\draw[%s] %s -- %s;\n" % ('edge', |
| 1319 | dict_drawing[index1][2], |
| 1320 | dict_drawing[index2][2]) |
| 1321 | |
| 1322 | # Start to write the output |
| 1323 | tikz_pic = '' |
| 1324 | tikz_pic += '\\begin{tikzpicture}%\n' |
| 1325 | tikz_pic += '\t[x={(%fcm, %fcm)},\n' % (RDF(rotation_matrix[0][0]), |
| 1326 | RDF(rotation_matrix[0][1])) |
| 1327 | tikz_pic += '\ty={(%fcm, %fcm)},\n' % (RDF(rotation_matrix[1][0]), |
| 1328 | RDF(rotation_matrix[1][1])) |
| 1329 | tikz_pic += '\tz={(%fcm, %fcm)},\n' % (RDF(rotation_matrix[2][0]), |
| 1330 | RDF(rotation_matrix[2][1])) |
| 1331 | tikz_pic += '\tscale=%f,\n' % scale |
| 1332 | tikz_pic += '\tback/.style={loosely dotted, thin},\n' |
| 1333 | tikz_pic += '\tedge/.style={color=%s, thick},\n' % edge_color |
| 1334 | tikz_pic += '\tfacet/.style={fill=%s,fill opacity=%f},\n' % (facet_color,opacity) |
| 1335 | tikz_pic += '\tvertex/.style={inner sep=1pt,circle,draw=%s!25!black,' % vertex_color |
| 1336 | tikz_pic += 'fill=%s!75!black,thick,anchor=base}]\n%%\n%%\n' % vertex_color |
| 1337 | |
| 1338 | # Draws the axes if True |
| 1339 | if axis: |
| 1340 | tikz_pic += '\\draw[color=black,thick,->] (0,0,0) -- (1,0,0) node[anchor=north east]{$x$};\n' |
| 1341 | tikz_pic += '\\draw[color=black,thick,->] (0,0,0) -- (0,1,0) node[anchor=north west]{$y$};\n' |
| 1342 | tikz_pic += '\\draw[color=black,thick,->] (0,0,0) -- (0,0,1) node[anchor=south]{$z$};\n' |
| 1343 | |
| 1344 | # Create the coordinate of the vertices: |
| 1345 | tikz_pic += '%% Coordinate of the vertices:\n%%\n' |
| 1346 | for v in dict_drawing: |
| 1347 | tikz_pic += dict_drawing[v][1] |
| 1348 | |
| 1349 | # Draw the interior by going in a cycle |
| 1350 | vertices = list(self.parent_polyhedron.Vrep_generator()) |
| 1351 | tikz_pic += '%%\n%%\n%% Drawing the interior\n%%\n' |
| 1352 | cyclic_vert = cyclic_sort_vertices_2d(list(self.parent_polyhedron.Vrep_generator())) |
| 1353 | cyclic_indices = [vertices.index(v) for v in cyclic_vert] |
| 1354 | tikz_pic += '\\fill[facet] ' |
| 1355 | for v in cyclic_indices: |
| 1356 | if v in dict_drawing: |
| 1357 | tikz_pic += '%s -- ' % dict_drawing[v][2] |
| 1358 | tikz_pic += 'cycle {};\n' |
| 1359 | |
| 1360 | # Draw the edges in the front |
| 1361 | tikz_pic += '%%\n%%\n%% Drawing edges\n%%\n' |
| 1362 | tikz_pic += edges |
| 1363 | |
| 1364 | # Finally, the vertices in front are drawn on top of everything. |
| 1365 | tikz_pic += '%%\n%%\n%% Drawing the vertices\n%%\n' |
| 1366 | for v in dict_drawing: |
| 1367 | tikz_pic += dict_drawing[v][0] |
| 1368 | tikz_pic += '%%\n%%\n\\end{tikzpicture}' |
| 1369 | |
| 1370 | return LatexExpr(tikz_pic) |
| 1371 | |
| 1372 | def _tikz_3d_in_3d(self, view, angle, scale, edge_color, |
| 1373 | facet_color, opacity, vertex_color, axis): |
| 1374 | r""" |
| 1375 | Return a string ``tikz_pic`` consisting of a tikz picture of ``self`` |
| 1376 | according to a projection ``view`` and an angle ``angle`` |
| 1377 | obtained via Jmol through the current state property. |
| 1378 | |
| 1379 | INPUT: |
| 1380 | |
| 1381 | - ``view`` - list (default: [0,0,1]) representing the rotation axis. |
| 1382 | - ``angle`` - integer angle of rotation in degree from 0 to 360. |
| 1383 | - ``scale`` - integer specifying the scaling of the tikz picture. |
| 1384 | - ``edge_color`` - string representing colors which tikz |
| 1385 | recognize. |
| 1386 | - ``facet_color`` - string representing colors which tikz |
| 1387 | recognize. |
| 1388 | - ``vertex_color`` - string representing colors which tikz |
| 1389 | recognize. |
| 1390 | - ``opacity`` - real number between 0 and 1 giving the opacity of |
| 1391 | the front facets. |
| 1392 | - ``axis`` - Boolean draw the axes at the origin or not. |
| 1393 | |
| 1394 | OUTPUT: |
| 1395 | |
| 1396 | - LatexExpr -- containing the TikZ picture. |
| 1397 | |
| 1398 | EXAMPLES:: |
| 1399 | |
| 1400 | sage: P = polytopes.small_rhombicuboctahedron() |
| 1401 | sage: Image = P.projection()._tikz_3d_in_3d([3,7,5], 100, scale=3, edge_color='blue', facet_color='orange', opacity=0.5, vertex_color='green', axis=True) |
| 1402 | sage: type(Image) |
| 1403 | <class 'sage.misc.latex.LatexExpr'> |
| 1404 | sage: print '\n'.join(Image.splitlines()[:4]) |
| 1405 | \begin{tikzpicture}% |
| 1406 | [x={(-0.046385cm, 0.837431cm)}, |
| 1407 | y={(-0.243536cm, 0.519228cm)}, |
| 1408 | z={(0.968782cm, 0.170622cm)}, |
| 1409 | sage: open('polytope-tikz1.tex', 'w').write(Image) # not tested |
| 1410 | """ |
| 1411 | view_vector = vector(RDF, view) |
| 1412 | rot = rotate_arbitrary(view_vector, -(angle/360)*2*pi) |
| 1413 | rotation_matrix = rot[:2].transpose() |
| 1414 | proj_vector = (rot**(-1))*vector(RDF, [0, 0, 1]) |
| 1415 | |
| 1416 | # First compute the back and front vertices and facets |
| 1417 | facets = self.face_inequalities |
| 1418 | front_facets = [] |
| 1419 | back_facets = [] |
| 1420 | for index_facet in range(len(facets)): |
| 1421 | A = facets[index_facet].vector()[1:] |
| 1422 | B = facets[index_facet].vector()[0] |
| 1423 | if A*(2000*proj_vector)+B < 0: |
| 1424 | front_facets += [index_facet] |
| 1425 | else: |
| 1426 | back_facets += [index_facet] |
| 1427 | |
| 1428 | vertices = list(self.parent_polyhedron.Vrep_generator()) |
| 1429 | front_vertices = [] |
| 1430 | for index_facet in front_facets: |
| 1431 | A = facets[index_facet].vector()[1:] |
| 1432 | B = facets[index_facet].vector()[0] |
| 1433 | for v in self.points: |
| 1434 | if A*self.coords[v]+B < 0.0005 and v not in front_vertices: |
| 1435 | front_vertices += [v] |
| 1436 | |
| 1437 | back_vertices = [] |
| 1438 | for index_facet in back_facets: |
| 1439 | A = facets[index_facet].vector()[1:] |
| 1440 | B = facets[index_facet].vector()[0] |
| 1441 | for v in self.points: |
| 1442 | if A*self.coords[v]+B < 0.0005 and v not in back_vertices: |
| 1443 | back_vertices += [v] |
| 1444 | |
| 1445 | # Creates the nodes, coordinate and tag for every vertex of the polytope. |
| 1446 | # The tag is used to draw the front facets later on. |
| 1447 | dict_drawing = {} |
| 1448 | back_part = '' |
| 1449 | front_part = '' |
| 1450 | |
| 1451 | for vert in self.points: |
| 1452 | v = self.coords[vert] |
| 1453 | v_vect = str([i.n(digits=3) for i in v]) |
| 1454 | v_vect = v_vect.replace('[','(') |
| 1455 | v_vect = v_vect.replace(']',')') |
| 1456 | tag = '%s' %v_vect |
| 1457 | node = "\\node[%s] at %s {};\n" % ('vertex', tag) |
| 1458 | coord = '\coordinate %s at %s;\n' %(tag, tag) |
| 1459 | dict_drawing[vert] = node, coord, tag |
| 1460 | |
| 1461 | # Separate the edges between back and front |
| 1462 | |
| 1463 | for index1, index2 in self.lines: |
| 1464 | # v1 = self.coords[index1] |
| 1465 | # v2 = self.coords[index2] |
| 1466 | |
| 1467 | H_v1 = set(self.parent_polyhedron.Vrepresentation(index1).incident()) |
| 1468 | H_v2 = set(self.parent_polyhedron.Vrepresentation(index2).incident()) |
| 1469 | H_v12 = [h for h in H_v1.intersection(H_v2) if h in back_facets] |
| 1470 | |
| 1471 | # The back edge has to be between two vertices in the Back |
| 1472 | # AND such that the 2 facets touching them are in the Back |
| 1473 | if index1 in back_vertices and index2 in back_vertices and len(H_v12)==2: |
| 1474 | back_part += "\\draw[%s,back] %s -- %s;\n" % ('edge', dict_drawing[index1][2], dict_drawing[index2][2]) |
| 1475 | else: |
| 1476 | front_part += "\\draw[%s] %s -- %s;\n" % ('edge',dict_drawing[index1][2],dict_drawing[index2][2]) |
| 1477 | |
| 1478 | # Start to write the output |
| 1479 | tikz_pic = '' |
| 1480 | tikz_pic += '\\begin{tikzpicture}%\n' |
| 1481 | tikz_pic += '\t[x={(%fcm, %fcm)},\n' % (RDF(rotation_matrix[0][0]), |
| 1482 | RDF(rotation_matrix[0][1])) |
| 1483 | tikz_pic += '\ty={(%fcm, %fcm)},\n' % (RDF(rotation_matrix[1][0]), |
| 1484 | RDF(rotation_matrix[1][1])) |
| 1485 | tikz_pic += '\tz={(%fcm, %fcm)},\n' % (RDF(rotation_matrix[2][0]), |
| 1486 | RDF(rotation_matrix[2][1])) |
| 1487 | tikz_pic += '\tscale=%f,\n' % scale |
| 1488 | tikz_pic += '\tback/.style={loosely dotted, thin},\n' |
| 1489 | tikz_pic += '\tedge/.style={color=%s, thick},\n' % edge_color |
| 1490 | tikz_pic += '\tfacet/.style={fill=%s,fill opacity=%f},\n' % (facet_color,opacity) |
| 1491 | tikz_pic += '\tvertex/.style={inner sep=1pt,circle,draw=%s!25!black,' % vertex_color |
| 1492 | tikz_pic += 'fill=%s!75!black,thick,anchor=base}]\n%%\n%%\n' % vertex_color |
| 1493 | |
| 1494 | # Draws the axes if True |
| 1495 | if axis: |
| 1496 | tikz_pic += '\\draw[color=black,thick,->] (0,0,0) -- (1,0,0) node[anchor=north east]{$x$};\n' |
| 1497 | tikz_pic += '\\draw[color=black,thick,->] (0,0,0) -- (0,1,0) node[anchor=north west]{$y$};\n' |
| 1498 | tikz_pic += '\\draw[color=black,thick,->] (0,0,0) -- (0,0,1) node[anchor=south]{$z$};\n' |
| 1499 | |
| 1500 | # Create the coordinate of the vertices |
| 1501 | tikz_pic += '%% Coordinate of the vertices:\n%%\n' |
| 1502 | for v in dict_drawing: |
| 1503 | tikz_pic += dict_drawing[v][1] |
| 1504 | |
| 1505 | # Draw the edges in the back |
| 1506 | tikz_pic += '%%\n%%\n%% Drawing edges in the back\n%%\n' |
| 1507 | tikz_pic += back_part |
| 1508 | |
| 1509 | # Draw the vertices on top of the back-edges |
| 1510 | tikz_pic += '%%\n%%\n%% Drawing vertices in the back\n%%\n' |
| 1511 | for v in back_vertices: |
| 1512 | if not v in front_vertices and v in dict_drawing: |
| 1513 | tikz_pic += dict_drawing[v][0] |
| 1514 | |
| 1515 | # Draw the facets in the front by going in cycles for every facet. |
| 1516 | tikz_pic += '%%\n%%\n%% Drawing the facets\n%%\n' |
| 1517 | for index_facet in front_facets: |
| 1518 | cyclic_vert = cyclic_sort_vertices_2d(list(facets[index_facet].incident())) |
| 1519 | cyclic_indices = [vertices.index(v) for v in cyclic_vert] |
| 1520 | tikz_pic += '\\fill[facet] ' |
| 1521 | for v in cyclic_indices: |
| 1522 | if v in dict_drawing: |
| 1523 | tikz_pic += '%s -- ' % dict_drawing[v][2] |
| 1524 | tikz_pic += 'cycle {};\n' |
| 1525 | |
| 1526 | # Draw the edges in the front |
| 1527 | tikz_pic += '%%\n%%\n%% Drawing edges in the front\n%%\n' |
| 1528 | tikz_pic += front_part |
| 1529 | |
| 1530 | # Finally, the vertices in front are drawn on top of everything. |
| 1531 | tikz_pic += '%%\n%%\n%% Drawing the vertices in the front\n%%\n' |
| 1532 | for v in self.points: |
| 1533 | if v in front_vertices: |
| 1534 | if v in dict_drawing: |
| 1535 | tikz_pic += dict_drawing[v][0] |
| 1536 | tikz_pic += '%%\n%%\n\\end{tikzpicture}' |
| 1537 | return LatexExpr(tikz_pic) |