Here is a general solution... but not completely since it can not manage the content of nodes (see below for a simpler solution but less general).
I create a new homothety
option usable with a path. This options can store the result of an homothetic transformation applied to this path. Some subkeys control the parameters:
scale
is used to specify the scale (default value: 1).
center
is used to specify the center (default value: {0,0}).
store in
is used to specify the macro that stores the transformed path.
name
is a prefix to name each vertex of the transformed path (default value: homothety
).
A little example to show the syntax
\draw[homothety={scale=2,center={1,1},name=A,store in=\transpath}] (0,0) -- (3,4);
As usual, the path is drawn. But in addition:
- A new path (the original path transformed by the homothety whose scale is 2 and center is (1,1)) is stored in
\transpath
macro.
- The vertices of this new path are
A-1
, A-2
, etc.
- The
homothetypoints
counter gives the number of vertices.
Then, to draw the transformed path with labels, you can use:
\draw \transpath;
\foreach \num in {1,...,\arabic{homothetypoints}}{
\node[below] (A-\num) {$A_\num$};
}
Strengths and limitations
- You can use
homothety
just to copy a path (with scale=1 and center={0,0}).
- The original path can use nodes, coordinates, holes in its definition.
- Each vertex of the transformed path is stored.
- But, the content of a node is not transformed...
A larger example (result)

A larger example (long commented code)
\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,decorations.pathreplacing,decorations.pathmorphing}
\makeatletter
% to produce automaticaly homothetic paths
\newcounter{homothetypoints} % number of vertices of path
\tikzset{
% homothety is a family...
homothety/.style={homothety/.cd,#1},
% ...with some keys
homothety={
% parameters
scale/.store in=\homothety@scale,% scale of current homothetic transformation
center/.store in=\homothety@center,% center of current homothetic transformation
name/.store in=\homothety@name,% prefix for named vertices
% default values
scale=1,
center={0,0},
name=homothety,
% initialization
init memoize homothetic path/.code={
\xdef#1{}
\setcounter{homothetypoints}{0}
},
% incrementation
++/.code={\addtocounter{homothetypoints}{1}},
% a style to store an homothetic transformation of current path into #1 macro
store in/.style={
init memoize homothetic path=#1,
/tikz/postaction={
decorate,
decoration={
show path construction,
moveto code={
% apply homothetic transformation to this segment and add result to #1
\xdef#1{#1 ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentfirst)$)}
% name this vertex
\coordinate[homothety/++](\homothety@name-\arabic{homothetypoints})
at ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentfirst)$);
},
lineto code={
% apply homothetic transformation to this segment and add result to #1
\xdef#1{#1 -- ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$)}
% name this vertex
\coordinate[homothety/++] (\homothety@name-\arabic{homothetypoints})
at ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$);
},
curveto code={
% apply homothetic transformation to this segment and add result to #1
\xdef#1{#1
.. controls ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentsupporta)$)
and ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentsupportb)$)
.. ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$)}
% name this vertex
\coordinate[homothety/++] (\homothety@name-\arabic{homothetypoints})
at ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$);
},
closepath code={
% apply homothetic transformation to this segment and add result to #1
\xdef#1{#1 -- cycle ($(\homothety@center)!\homothety@scale!(\tikzinputsegmentlast)$)}
},
},
},
},
},
}
\makeatother
\begin{document}
\begin{tikzpicture}[font=\bfseries\sffamily]
% some styles
\tikzset{
dashed line/.style={draw=#1!50!gray,dashed,line width=.4pt},
filled shape/.style={draw=black,line width=1pt,fill=#1,fill opacity=.4},
dot/.style={draw,line width=.4pt,fill=#1!50!gray},
}
% draw a path (and memomize its definition into \mypath with points named A-1, A-2,...)
\draw[filled shape=cyan,homothety={store in=\mypath,name=A}]
(0,0) to[bend right] ++(2,2) -- ++(-1,1) to[bend left] ++(-2,-2) -- cycle;
% add a label to each vertex
\pgfmathsetmacro{\nbpoints}{\arabic{homothetypoints}}
\foreach \num in {1,...,\nbpoints} {
\node[above] at (A-\num) {$A_\num$};
}
% first center: c1
\fill[dot=green] (0,3) coordinate (c1) circle(2pt) node[right]{$c_1$};
% store two homothetic transformations of \mypath
\path[homothety={store in=\secondpath,scale=-1,center=c1}] \mypath;
\path[homothety={store in=\thirdpath,scale=-2,center=c1,name=B}] \mypath;
% draw them
\draw[filled shape=green] \secondpath;
\draw[filled shape=green] \thirdpath;
% for each vertex of \thirdpath, add a label and draw a dashed line to
% corresponding vertex of \mypath
\foreach \num in {1,...,\nbpoints} {
\node[below] at (B-\num) {$B_\num$};
\draw[dashed line=green] (B-\num) -- (A-\num);
}
% second center: c2
\fill[dot=red] (-4,-1) coordinate (c2) circle(2pt) node[above]{$c_2$};
% store two homothetic transformations of \mypath
\path[homothety={store in=\secondpath,scale=2,center=c2,name=C}] \mypath;
\path[homothety={store in=\thirdpath,scale=.5,center=c2}] \mypath;
% draw them
\draw[filled shape=red] \secondpath;
\draw[filled shape=red] \thirdpath;
% for each vertex of \thirdpath, draw a dashed line to center and add a label
\foreach \num in {1,...,\nbpoints} {
\node[above] at (C-\num) {$C_\num$};
\draw[dashed line=red] (C-\num) -- (c2);
}
\end{tikzpicture}
\end{document}
Simple solution but with limitations
You can use calc
library and scopes with scale
and shift
options to draw homothetic transformations. It is simple but your path must be defined only by numeric coordinates.
Result:

Code (commented):
\documentclass[margin=5mm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
% some styles
\tikzset{
filled shape/.style={draw=black,line width=1pt,fill=#1,fill opacity=.4},
dot/.style={draw,line width=.4pt,fill=#1!50!gray},
homothety at/.style args={#1 scaled by #2}{shift={($(#1)!#2!(0,0)$)},scale=#2},
}
% path definition (numeric coordinates only!)
\def\mypath{(0,0) to[bend right] ++(2,2) -- ++(-1,1) to[bend left] ++(-2,-2) -- cycle}
% draw this path
\draw[filled shape=cyan] \mypath;
% center of homothetic transformation
\fill[dot=green] (-1,2) coordinate (c1) circle(2pt) node[above]{$c_1$};
% first transformation (scale=-1, center=c1)
\begin{scope}[homothety at=c1 scaled by -1]
\draw[filled shape=red] \mypath;
\end{scope}
% second transformation (scale=2, center=c1)
\begin{scope}[homothety at=c1 scaled by 2]
\draw[filled shape=red] \mypath;
\draw[dashed] (c1) -- (0,0);
\draw[dashed] (c1) -- (2,2);
\draw[dashed] (c1) -- (1,3);
\draw[dashed] (c1) -- (-1,1);
\end{scope}
\end{tikzpicture}
\end{document}
draw-this-for-me
question. – Jake Sep 16 '12 at 18:39