An isometric view of a random city.
Do you have a question regarding this example, TikZ or LaTeX in general? Just ask in the
LaTeX Forum.
Oder frag auf Deutsch auf TeXwelt.de.
En français: TeXnique.fr.
% Random city
% Author: Pascal Seppecher
\documentclass[tikz,border=10pt]{standalone}
\usetikzlibrary{backgrounds}
\usepackage{ifthen}
% The blue print color
\definecolor{blueprintcolor}{RGB}{20,20,100}
% The shadow color
\colorlet{shadow}{blueprintcolor!50!white}
% The light color
\colorlet{light}{white!90!blueprintcolor}
% The background color
\colorlet{background}{blueprintcolor}
% The basic size of a block
\newcommand\defaultside{0.6}
% The height of a storey
\newcommand\floorheight{0.08}
% The minimum number of stories
\newcommand\storeymin{20}
% The maximum number of stories
\newcommand\storeymax{40}
% The width of a window
\newcommand\window{0.05}
% The angles of x,y-axes
\newcommand\xaxis{210}
\newcommand\yaxis{-30}
% Facade style random list
\pgfmathdeclarerandomlist{facade}{{\hlines}{\vlines}{\grid}{\grid}{\grid}}
% Vertical thickness
\newcommand\vthickness{thin}
% Horizontal thickness
\newcommand\hthickness{thin}
% Selects at random the thickness of the horizontal lines
\newcommand\setvthickness{
\pgfmathrandominteger{\alea}{0}{3}
\ifthenelse{\alea=0}{\renewcommand\vthickness{thick}}{}
\ifthenelse{\alea=1}{\renewcommand\vthickness{thin}}{}
\ifthenelse{\alea=2}{\renewcommand\vthickness{very thin}}{}
\ifthenelse{\alea=3}{\renewcommand\vthickness{ultra thin}}{}
}
% Selects at random the thickness of the vertical lines
\newcommand\seththickness{
\pgfmathrandominteger{\alea}{0}{3}
\ifthenelse{\alea=0}{\renewcommand\hthickness{thick}}{}
\ifthenelse{\alea=1}{\renewcommand\hthickness{thin}}{}
\ifthenelse{\alea=2}{\renewcommand\hthickness{very thin}}{}
\ifthenelse{\alea=3}{\renewcommand\hthickness{ultra thin}}{}
}
% Draws vertical lines on each side of the block
\newcommand\vlines[2]{
\pgfmathsetmacro\size{#1 * \floorheight}
\pgfmathsetmacro\max{#2/\window}
\foreach \col in {1,...,\max}
{
\pgfmathsetmacro\xx{-\col * \window}
\draw[\vthickness,draw=shadow, shift={(\yaxis:\xx)}] (0,0)--(0,\size);
\draw[\vthickness,draw=light, shift={(\xaxis:\xx)}] (0,0)--(0,\size);
}
}
% Draws horizontal lines on each side of the block
\newcommand\hlines[2]{
\foreach \floor in {0,...,#1}
{
\pgfmathsetmacro\z{\floor * \floorheight}
\draw[\hthickness,draw=shadow, shift={(90:\z)}] (150:#2)--(0,0);
\draw[\hthickness,draw=light, shift={(90:\z)}] (0,0) -- (30:#2);
}
}
% Draws horizontal and vertical lines on each side of the block
\newcommand\grid[2]{
\vlines{#1}{#2}
\hlines{#1} {#2}
}
% Draws a block at the specified position
\newcommand\block[2]{
% Computes the height of the block
\pgfmathsetmacro\height{#2 * \floorheight}
% Erases the background
\fill[fill=background]
(0,0) -- (150:#1) -- ++(0,\height) -- (0,\height) -- (0,0);
\fill[fill=background]
(0,0) -- (30:#1) -- ++(0,\height) -- (0,\height) -- (0,0);
% Draws the facades
\facade{\stories}{#1}
% Frames the facades
\draw[draw=shadow] (0,0) -- (150:#1) -- ++(0,\height) -- (0,\height) -- (0,0);
\draw[draw=light] (0,0) -- (30:#1) -- ++(0,\height) -- (0,\height) -- (0,0);
% Draws the terrace
\fill[fill=background, draw=light,shift={(90:\height)}]
(0,0) -- (30:#1) -- (0,#1) --(150:#1)--(0,0);
%
\pgfmathrandominteger{\alea}{0}{3}
\ifthenelse{\alea=0}{
% Sometimes, adds more stores (= skyscraper)
\begin{scope}[shift={(0,\height)},shift={(0,0.05)}]
\pgfmathsetmacro\pside{#1-0.1}
\pgfmathrandominteger{\stories}{2}{\storeymax}
\block{\pside}{\stories}
\end{scope}
}{}
\ifthenelse{\alea=1}{
% Sometimes, draws a pyramid roof
\pyramid{\height}{#1}
}{}
}
% Draws a basic block
\newcommand\basicblock[3]{
% Selects a random facade style
\pgfmathrandomitem{\facade}{facade}
\setvthickness{}
\seththickness{}
% Selects a random number of stores
\pgfmathrandominteger{\stories}{\storeymin}{\storeymax}
\begin{scope}[shift={(\xaxis:#1)},shift={(\yaxis:#2)}]
\block{#3}{\stories}
\end{scope}
}
% Draws a pyramid roof
\newcommand\pyramid[2]{
% Computes the side of the pyramid
\pgfmathsetmacro\pside{#2-0.1}
% Selects the height of the pyramid at random
\pgfmathparse{random()}
\pgfmathsetmacro\top{0.5+\pgfmathresult/3}
% Draws the pyramid
\begin{scope}[fill=background, draw=light,shift={(90:#1)},shift={(90:0.05)}]
\fill[draw=light] (0,0) -- (30:\pside) -- (0,\top) -- (150:\pside)--(0,0);
\draw (0,0) -- (0,\top);
\end{scope}
}
% Draws a random city of the specified dimensions
\newcommand\city[2]{
\foreach \x in {1,...,#1}
\foreach \y in {1,...,#2}
{\basicblock{\x}{\y}{\defaultside}}
}
\begin{document}
% Draws a hundred blocks random city
\begin{tikzpicture}[show background rectangle,
background rectangle/.style={fill=background}]
\city{10}{10}
\end{tikzpicture}
\end{document}
Comments
Adding comments is currently not enabled.