Ask Your Question
1

Generating Tikz codes from Sage for drawing scattering points in 3D

asked 2017-09-17 19:20:01 -0500

jim gravatar image

I am a beginner in Sage and Tikz, and have written the following snippet of Sage code:

P = Polyhedron(ieqs=[(30, -2, -2, -1), (25, -1.5, -2, -3),(20,-2,-1,-1), (0, 1, 0, 0), (0, 0, 1, 0), (0, 0, 0, 1)])
pts = P.integral_points()
point3d(pts,rgbcolor=(1,0, 0), size=10) + P.plot(rgbcolor = 'yellow', opacity = 0.5)

The purpose of the codes is to generate the integral points interior to the polytopes bound by 6 inequalities as given in the codes. The output is in the following link:

http://www.cse.cuhk.edu.hk/~jlee/dots.png (www.cse.cuhk.edu.hk/~jlee/dots.png)

I tried to follow the following reference:

doc.sagemath.org/html/en/thematic_tutorials/polytope_tikz.html

to generate Tikz codes for LaTeX and failed. Unlike Polyhedron which is a kind of object that can respond to "projection", point3d generates only a Graphics3D object which doesn't understand "projection".

Is there any way to output these points to Tikz?

Also, is it possible to ask Sage to color each of the facets of the polytope in different colors (just like Tikz can)?

Many thanx in advance!

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
1

answered 2017-09-18 01:42:48 -0500

dan_fulea gravatar image

updated 2017-09-18 01:53:14 -0500

The following is a possibility to get a picture:

import re
P = Polyhedron( ieqs=[ (30, -2  , -2, -1),
                       (25, -1.5, -2, -3),
                       (20, -2  , -1, -1),
                       ( 0,  1  ,  0,  0),
                       ( 0,  0  ,  1,  0),
                       ( 0,  0  ,  0,  1), ] )
tex = P.projection().tikz( view=[775,386,500], angle=105, scale=0.7, opacity=0.1 )
tex = re.sub( r'\\end\{tikzpicture\}'
              , '% \end{tikzpicture} % manually commented, we still have to work'
              , tex )

for v in P.integral_points():
    tex += ( '\n\\node[inner sep=1pt,circle,draw=red!25!black,fill=red!75!black,thick,anchor=base] at (%s, %s, %s) {};'
             % tuple(v) )

tex += '\n\n\\end{tikzpicture}'
print tex

The view point, and maybe all optional parameters declared above should be change to follow the given needs.

The string tex contains the tikz code to be inserted in a valid $\LaTeX$ document, with correct imports for tikz, e.g.

\usepackage{tikz}

should be enough. Here, as a matter of taste, manual adjustments of the code are still needed. For instance:

The faces are colored w.r.t. the specifications in the lines starting with \fill[facet], and the facet style is declared in

\begin{tikzpicture}%
    [x={(0.497546cm, 0.859773cm)},
    y={(-0.106336cm, -0.071189cm)},
    z={(0.860895cm, -0.505690cm)},
    scale=0.700000,
    back/.style={loosely dotted, thin},
    edge/.style={color=blue!95!black, thick},
    facet/.style={fill=blue!95!black,fill opacity=0.100000},
    vertex/.style={inner sep=1pt,circle,draw=green!25!black,fill=green!75!black,thick,anchor=base}]

If you need special colors for each face, than define them either inside the \begin{tikzpicture}[ ... ] as facet1/.style={...} or directly at the right place. The back style should also be adjusted. Herein is also a good place to insert for instance something like

latticepoint/.style={inner sep=1pt,circle,draw=red!25!black,fill=red!75!black,thick,anchor=base}

and to use this style in the changed line of code

tex += ( '\n\\node[latticepoint] at (%s, %s, %s) {};' % tuple(v) )

to have a more compact $\LaTeX$ code. This should be a good start, good luck!

edit flag offensive delete link more

Comments

Thanx, Dan!

jim gravatar imagejim ( 2017-09-19 06:39:11 -0500 )edit

You can change the vertex, edge and facet color directly in the tikz method using the parameters "vertex_color", "edge_color" and "facet_color". They can take any string argument which tikz can interpret as a color. One slight issue with the above loop on integral points is that it may not iterate the interior lattice points according to the projection, i.e. from the furthest to closest to the screen, and maybe some point nodes intersect in a weird way. You could sort them as follows:

proj_vector = vector([775,386,500])
linear_proj = [(proj_vector*p,p) for p in P.integral_points()]
linear_proj.sort()
for v in linear_proj:
   tex += ( '\n\\node[inner sep=1pt,circle,draw=red!25!black,fill=red!75!black,thick,anchor=base] at (%s, %s, %s) {};' %tuple(v[1])
jipilab gravatar imagejipilab ( 2017-10-09 06:45:57 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2017-09-17 19:20:01 -0500

Seen: 37 times

Last updated: Sep 18