Graphics, Figures & Tablestikz-3dplot | Circles and Spheres distorted

Information and discussion about graphics, figures & tables in LaTeX documents.
Post Reply
Illuminatiii
Posts: 5
Joined: Wed Aug 15, 2012 10:58 pm

tikz-3dplot | Circles and Spheres distorted

Post by Illuminatiii »

Hello,

I am struggling with tikz-3dplot. I am trying to make a crystal lattice, with atoms at certain coordinates. This I have achieved, however when rotating the axis to get a "better" view of the lattice structure the spherical shapes gets distorted.

I would like to have them spherical, and I have tried to mess with different elliptical settings, however none seem to work.

I would think that it would be possible to transform the coordinate system, and then draw the circles just as circles, and not in scale with the rotation.

Hopefully some of you guys know if this is possible or not.

Here is the code

Code: Select all

\begin{figure}[!h]
% Define block styles
\centering
	
\tdplotsetmaincoords{75}{10}
\begin{tikzpicture}[tdplot_main_coords, scale = 5]

\shadedraw[ball color = blue] (-1,0,0.8) circle (0.1) node[right]{~~~~~~A-site cation};
\shadedraw[ball color = yellow] (-1,0,0.6) ellipse (0.08 and 0.13) node[right]{~~~~~~B-site cation};
\shadedraw[ball color = red] (-1,0,0.4) ellipse (0.03 and 0.04) node[right]{~~~~~~Oxygen ion};


%---bottom layer A-site -----
\shadedraw[ball color = blue] (0,0,0) ellipse (0.10 and 0.15);
\shadedraw[ball color = blue] (1,0,0) ellipse (0.1 and 0.15);
\shadedraw[ball color = blue] (0,1,0) ellipse (0.1 and 0.15);
\shadedraw[ball color = blue] (1,1,0) ellipse (0.1 and 0.15);
%----- top layer A-site -----
\shadedraw[ball color = blue] (0,0,1) ellipse (0.1 and 0.15);
\shadedraw[ball color = blue] (1,0,1) ellipse (0.1 and 0.15);
\shadedraw[ball color = blue] (0,1,1) ellipse (0.1 and 0.15);
\shadedraw[ball color = blue] (1,1,1) ellipse (0.1 and 0.15);
% ----- B-site ion ------
\shadedraw[ball color = yellow] (0.5,0.5,0.5) ellipse (0.08 and 0.11);
% ----- Oxygen ions -------
\shadedraw[ball color = red] (0.5,0.5,0) ellipse (0.03 and 0.04);
\shadedraw[ball color = red] (0.5,0,0.5) ellipse (0.03 and 0.04);
\shadedraw[ball color = red] (0,0.5,0.5) ellipse (0.03 and 0.04);
\shadedraw[ball color = red] (1,0.5,0.5) ellipse (0.03 and 0.04);
\shadedraw[ball color = red] (0.5,1,0.5) ellipse (0.03 and 0.04);
\shadedraw[ball color = red] (0.5,0.5,1) ellipse (0.03 and 0.04);

% ---- Planes -----
\path[draw, fill=green!20, opacity=0.5] (0.5,0.5,0) -- (1,0.5,0.5) -- (0.5,1,0.5) -- (0.5,0.5,0);
\path[draw, fill=red!10, opacity=0.5] (0.5,0.5,0) -- (1,0.5,0.5) -- (0.5,0,0.5) -- (0.5,0.5,0);
\path[draw, fill=red!10, opacity=0.5] (0.5,0.5,0) -- (0.5,0,0.5) -- (0,0.5,0.5) -- (0.5,0.5,0);
\path[draw, fill=green!20, opacity=0.5] (0.5,0.5,0) -- (0.5,1,0.5) -- (0,0.5,0.5) -- (0.5,0.5,0);
\path[draw, fill=green!20, opacity=0.5] (0.5,0.5,1) -- (1,0.5,0.5) -- (0.5,1,0.5) -- (0.5,0.5,1);
\path[draw, fill=red!10, opacity=0.5] (0.5,0.5,1) -- (1,0.5,0.5) -- (0.5,0,0.5) -- (0.5,0.5,1);
\path[draw, fill=red!10, opacity=0.5] (0.5,0.5,1) -- (0.5,0,0.5) -- (0,0.5,0.5) -- (0.5,0.5,1);
\path[draw, fill=green!20, opacity=0.5] (0.5,0.5,1) -- (0.5,1,0.5) -- (0,0.5,0.5) -- (0.5,0.5,1);
% ---- Drawing lattice lines ----
\draw[thin] (0,0,0) -- (1,0,0) -- (1,1,0) -- (0,1,0) -- (0,0,0);
\draw[thin] (0,0,1) -- (1,0,1) -- (1,1,1) -- (0,1,1) -- (0,0,1);
\draw[thin] (0,0,0) -- (0,0,1);
\draw[thin] (1,0,0) -- (1,0,1);
\draw[thin] (1,1,0) -- (1,1,1);
\draw[thin] (0,1,0) -- (0,1,1);

\end{tikzpicture}
\end{figure}
Attachments
Capture.PNG
Capture.PNG (51.75 KiB) Viewed 8836 times

Recommended reading 2024:

LaTeXguide.org • LaTeX-Cookbook.net • TikZ.org

NEW: TikZ book now 40% off at Amazon.com for a short time.

heinjd
Posts: 2
Joined: Thu Aug 16, 2012 1:51 pm

tikz-3dplot | Circles and Spheres distorted

Post by heinjd »

Hi Illuminatiii,

There are a couple handy commands and styles in tikz-3dplot that will give you exactly what you're looking for. Since these balls are two-dimensional drawings, the act of drawing them in the main coordinate frame of tikz-3dplot will show them in a rotated sense, which spoils the three-dimensional illusion that they are intended to give. But you can specify to draw anything in the "screen" coordinate frame (unrotated) by using the tdplot_screen_coords style in your drawing command.

First, let's look at the table you are generating to the left of the lattice image. You can explicitly define the position of each entry using screen coordinates, which will not be affected by the choice of rotation for the main coordinate frame.

Code: Select all

\shadedraw[tdplot_screen_coords,ball color = blue] (-1,1) circle (0.1) node[right,xshift=1cm]{A-site cation};
\shadedraw[tdplot_screen_coords,ball color = yellow] (-1,0.7) circle (0.08) node[right,xshift=1cm]{B-site cation};
\shadedraw[tdplot_screen_coords,ball color = red] (-1,0.4) circle (0.03) node[right,xshift=1cm]{Oxygen ion};
Note the use of the tdplot_screen_coords in the style description, and the use of two-dimensional coordinates for the circles.

Next, we can make use of this style for drawing the sites in the lattice. But we can't hard-code the location of each site like we did in the table of contents, as we want these to move if you change the orientation of the main coordinate frame. There is a handy command called \tdplottransformmainscreen that will transform a set of coordinates defined in the main coordinate frame, and calculate the equivalent coordinate in the screen coordinate frame. This will give us a way of locating the points in the screen coordinate frame, based on their original location in the main coordinate frame.

Here's a couple examples.

Code: Select all

\tdplottransformmainscreen{0}{0}{0}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

\tdplottransformmainscreen{1}{0}{0}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

%...

\tdplottransformmainscreen{0.5}{1}{0.5}
\shadedraw[tdplot_screen_coords, ball color = red] (\tdplotresx,\tdplotresy) circle (0.03);
Now, this isn't as elegant as I would like it to be. It would be nicer if we could define coordinates for each lattice site using the tikz convention, and then draw all lattice sites using these coordinates. Unfortunately, it looks like tikz-3dplot does not behave properly when dealing with these types of coordinates. I can't recall off the top of my head why, but I have notes throughout the style package saying it doesn't work properly, and no solution had been discovered. I'll trust my past self and assume it's still the case. So suffice to say that doing it in this example works, but is not as elegant as it should be.

Putting these altogether, here's your complete code, modified with my suggestions.

Code: Select all

\begin{figure}[!h]
% Define block styles
\centering

\tdplotsetmaincoords{75}{10}
\begin{tikzpicture}[tdplot_main_coords, scale = 5]

\shadedraw[tdplot_screen_coords,ball color = blue] (-1,1) circle (0.1) node[right,xshift=1cm]{A-site cation};
\shadedraw[tdplot_screen_coords,ball color = yellow] (-1,0.7) circle (0.08) node[right,xshift=1cm]{B-site cation};
\shadedraw[tdplot_screen_coords,ball color = red] (-1,0.4) circle (0.03) node[right,xshift=1cm]{Oxygen ion};


%---bottom layer A-site -----

\tdplottransformmainscreen{0}{0}{0}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

\tdplottransformmainscreen{1}{0}{0}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

\tdplottransformmainscreen{0}{1}{0}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

\tdplottransformmainscreen{1}{1}{0}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

%----- top layer A-site -----

\tdplottransformmainscreen{0}{0}{1}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

\tdplottransformmainscreen{1}{0}{1}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

\tdplottransformmainscreen{0}{1}{1}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);

\tdplottransformmainscreen{1}{1}{1}
\shadedraw[tdplot_screen_coords, ball color = blue] (\tdplotresx,\tdplotresy) circle (0.10);



% ----- B-site ion ------

\tdplottransformmainscreen{0.5}{0.5}{0.5}
\shadedraw[tdplot_screen_coords, ball color = yellow] (\tdplotresx,\tdplotresy) circle (0.08);


% ----- Oxygen ions -------

\tdplottransformmainscreen{0.5}{0.5}{0}
\shadedraw[tdplot_screen_coords, ball color = red] (\tdplotresx,\tdplotresy) circle (0.03);

\tdplottransformmainscreen{0.5}{0}{0.5}
\shadedraw[tdplot_screen_coords, ball color = red] (\tdplotresx,\tdplotresy) circle (0.03);

\tdplottransformmainscreen{0}{0.5}{0.5}
\shadedraw[tdplot_screen_coords, ball color = red] (\tdplotresx,\tdplotresy) circle (0.03);

\tdplottransformmainscreen{1}{0.5}{0.5}
\shadedraw[tdplot_screen_coords, ball color = red] (\tdplotresx,\tdplotresy) circle (0.03);

\tdplottransformmainscreen{0.5}{1}{0.5}
\shadedraw[tdplot_screen_coords, ball color = red] (\tdplotresx,\tdplotresy) circle (0.03);

\tdplottransformmainscreen{0.5}{0.5}{1}
\shadedraw[tdplot_screen_coords, ball color = red] (\tdplotresx,\tdplotresy) circle (0.03);

% ---- Planes -----
\path[draw, fill=green!20, opacity=0.5] (0.5,0.5,0) -- (1,0.5,0.5) -- (0.5,1,0.5) -- (0.5,0.5,0);
\path[draw, fill=red!10, opacity=0.5] (0.5,0.5,0) -- (1,0.5,0.5) -- (0.5,0,0.5) -- (0.5,0.5,0);
\path[draw, fill=red!10, opacity=0.5] (0.5,0.5,0) -- (0.5,0,0.5) -- (0,0.5,0.5) -- (0.5,0.5,0);
\path[draw, fill=green!20, opacity=0.5] (0.5,0.5,0) -- (0.5,1,0.5) -- (0,0.5,0.5) -- (0.5,0.5,0);
\path[draw, fill=green!20, opacity=0.5] (0.5,0.5,1) -- (1,0.5,0.5) -- (0.5,1,0.5) -- (0.5,0.5,1);
\path[draw, fill=red!10, opacity=0.5] (0.5,0.5,1) -- (1,0.5,0.5) -- (0.5,0,0.5) -- (0.5,0.5,1);
\path[draw, fill=red!10, opacity=0.5] (0.5,0.5,1) -- (0.5,0,0.5) -- (0,0.5,0.5) -- (0.5,0.5,1);
\path[draw, fill=green!20, opacity=0.5] (0.5,0.5,1) -- (0.5,1,0.5) -- (0,0.5,0.5) -- (0.5,0.5,1);

% ---- Drawing lattice lines ----
\draw[thin] (0,0,0) -- (1,0,0) -- (1,1,0) -- (0,1,0) -- (0,0,0);
\draw[thin] (0,0,1) -- (1,0,1) -- (1,1,1) -- (0,1,1) -- (0,0,1);
\draw[thin] (0,0,0) -- (0,0,1);
\draw[thin] (1,0,0) -- (1,0,1);
\draw[thin] (1,1,0) -- (1,1,1);
\draw[thin] (0,1,0) -- (0,1,1);

\end{tikzpicture}
\end{figure}
See the attachment below for an example of this code. You will now be able to change your perspective of the lattice by adjusting the rotation of the main coordinate frame, and the locations will change accordingly, while the table of contents will remain fixed.

Note that you may want to change the order in which you draw certain objects. Note in this example that the oxygen atom at (0.5,0.5,0) appears to be inside the shaded region. To fix this, you can draw this object, or any that should be "in front" of others, later in the drawing order.

Hope this answers your questions!

Jeff
Attachments
lattice.png
lattice.png (52.38 KiB) Viewed 8816 times
User avatar
Stefan Kottwitz
Site Admin
Posts: 10344
Joined: Mon Mar 10, 2008 9:44 pm

tikz-3dplot | Circles and Spheres distorted

Post by Stefan Kottwitz »

Hi Illuminatiii, hi Jeff,

nice example and solution - is it ok if we post the example in the TikZ Example Gallery?

Stefan
LaTeX.org admin
heinjd
Posts: 2
Joined: Thu Aug 16, 2012 1:51 pm

tikz-3dplot | Circles and Spheres distorted

Post by heinjd »

Hi Stefan,

I have no problem with posting this as an example, but since Illuminatiii is the original author, I'll leave it for him to decide.


Jeff
josephwright
Site Moderator
Posts: 814
Joined: Tue Jul 01, 2008 2:19 pm

Re: tikz-3dplot | Circles and Spheres distorted

Post by josephwright »

Wow: this is going in my lecturer slides on crystallography!
Joseph Wright
Illuminatiii
Posts: 5
Joined: Wed Aug 15, 2012 10:58 pm

Re: tikz-3dplot | Circles and Spheres distorted

Post by Illuminatiii »

Jeff,

this was just what I wanted! And your explanation helped me understand a lot more about the package. I was reading in the manual but man, but your explanation was easy to follow. A huge thank you

Go ahead Stefan and use this as an example! I am sure there are many more students, and new users to LaTeX (like me) which would find this solution helpful!
Post Reply