Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I would like to draw a rectangle along the border of a circle. The \draw with the \angle operation might do it, but it is rather cumbersome.
I was wondering if there is another more elegant/shorter solution, i.e. a command that draws shapes along other shapes.

Ok sorry for the late update. What I want to do is more something along the following: Rectangle 'along' a circle

A (badly) drawn rectangle following the border of a circle.

share|improve this question
3  
Please show us what you have done so far, supply a MWE. In fact I do not really know what you want. A rectangle along a circle? Is the rectangle then also a curved path? Or is it just a rectangle on the border at a certain angle? –  zeroth Jan 20 '12 at 16:48
    
I was hoping for the rectangle to also be a curved path, pretty much outlining a region of the circle's border. –  Alex Frechette Jan 23 '12 at 15:35
1  
Well if it is a curved path, then it is not really a rectangle. –  Peter Grill Jan 23 '12 at 18:02
add comment

2 Answers

up vote 16 down vote accepted

Draw Arched "Rectangle" Around Circle:

Below is a macro that draws the desired shape around the circle: \DrawAlong{(Center)}{\Radius}{\Separation}{120}{60} yields the blue shape from 120 to 60 degrees, and \DrawAlong[draw=black,fill=yellow, fill opacity=0.4]{(Center)}{\Radius}{\Separation}{-30}{-60} yields the filled in yellow shape from -30 to -60 degrees:

enter image description here

Further Enhancements

  • The code can probably be greatly simplified by using polar coordinates.

Code:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\newdimen\XCoord%
\newdimen\YCoord%

\makeatletter
\newlength{\My@OuterArcRadius}
\newlength{\My@InnerArcRadius}
\newlength{\My@OuterXStart}
\newlength{\My@OuterYStart}
\newlength{\My@OuterXEnd}
\newlength{\My@OuterYEnd}
\newlength{\My@InnerXStart}
\newlength{\My@InnerYStart}
\newlength{\My@InnerXEnd}
\newlength{\My@InnerYEnd}
%
\newcommand*{\DrawAlong}[6][]{%
    % [#1] = style (optional)
    % {#2} = center
    % {#3} = radius
    % {#4} = separation
    % {#5} = arch angle start
    % {#6} = arc angle end
    \def\My@center{#2}%
    \def\My@radius{#3}%
    \def\My@separation{#4}%
    \def\My@arcStart{#5}%
    \def\My@arcEnd{#6}%
    %
    \pgfmathsetlength{\My@OuterArcRadius}{\My@radius+\My@separation}
    \pgfmathsetlength{\My@InnerArcRadius}{\My@radius-\My@separation}
    %
    % Extract coordinates of center: (XCoord,YCoord)
    % http://tex.stackexchange.com/questions/33703/extract-x-y-coordinate-of-an-arbitrary-point-in-tikz/33706#33706
    \path \My@center; \pgfgetlastxy{\XCoord}{\YCoord}
    %
    \pgfmathsetlength{\My@OuterXStart}{\XCoord+(\My@OuterArcRadius*cos(\My@arcStart))}
    \pgfmathsetlength{\My@OuterYStart}{\YCoord+(\My@OuterArcRadius*sin(\My@arcStart))}
    \pgfmathsetlength{\My@OuterXEnd}{\XCoord+(\My@OuterArcRadius*cos(\My@arcEnd))}
    \pgfmathsetlength{\My@OuterYEnd}{(\YCoord+\My@OuterArcRadius*sin(\My@arcEnd))}
    %
    \pgfmathsetlength{\My@InnerXStart}{\XCoord+(\My@InnerArcRadius*cos(\My@arcStart))}
    \pgfmathsetlength{\My@InnerYStart}{\YCoord+(\My@InnerArcRadius*sin(\My@arcStart))}
    \pgfmathsetlength{\My@InnerXEnd}{(\XCoord+\My@InnerArcRadius*cos(\My@arcEnd))}
    \pgfmathsetlength{\My@InnerYEnd}{(\YCoord+\My@InnerArcRadius*sin(\My@arcEnd))}
    %
    \draw [ultra thick, blue,#1] 
        (\My@OuterXStart,\My@OuterYStart)
        arc (\My@arcStart:\My@arcEnd:\My@OuterArcRadius)
        -- (\My@InnerXEnd, \My@InnerYEnd)
        arc (\My@arcEnd:\My@arcStart:\My@InnerArcRadius)
        --cycle;
}%
\makeatother

\begin{document}
\newcommand*{\Radius}{2cm}%
\newcommand*{\Separation}{0.2cm}%
%
\begin{tikzpicture}[ultra thick]
  \coordinate (Center) (1cm,3cm);

  \DrawAlong{(Center)}{\Radius}{\Separation}{120}{60}
  \DrawAlong[draw=black,fill=yellow, fill opacity=0.4]{(Center)}{\Radius}{\Separation}{-30}{-60}
  \draw [red ] (Center) circle    (\Radius);
\end{tikzpicture}
\end{document}

Draw Rectangle Around Circle:

If you know the radius of the circle, you can simple coordinate calculations to draw the rectangle. The circle radius is specified in \Radius and \Separation defines the separation you want between the circle and rectangle:

enter image description here

Alternatively, you could define a custom shape that has a rectangle around the circle, then simply using it as a node shape you would obtain the desired results:

enter image description here

Code: Known Radius:

\documentclass{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand*{\Radius}{2cm}%
\newcommand*{\Separation}{2pt}%

\begin{document}
\begin{tikzpicture}[ultra thick]
  \coordinate (Center) (1cm,3cm);

  \draw [red ] (Center) circle    (\Radius);
  \draw [blue] ($(Center)-(\Radius,\Radius)-(\Separation,\Separation)$) rectangle (\Radius+\Separation,\Radius+\Separation);
\end{tikzpicture}
\end{document}

Code: Node Shape

This is a modified version from How to draw inside a TikZ node, using node style?

\documentclass{article}
\usepackage{tikz}

\makeatletter
\pgfdeclareshape{CircleRectangle}
%
% Rectangle with an inscribed circle. Based on 'circle' shape
%
{%
  % All anchors are taken from the 'circle' shape:
  \inheritsavedanchors[from={circle}]%
  \inheritanchor[from={circle}]{center}%
  \inheritanchor[from={circle}]{mid}%
  \inheritanchor[from={circle}]{base}%
  \inheritanchor[from={circle}]{north}%
  \inheritanchor[from={circle}]{south}%
  \inheritanchor[from={circle}]{west}%
  \inheritanchor[from={circle}]{east}%
  \inheritanchor[from={circle}]{mid west}%
  \inheritanchor[from={circle}]{mid east}%
  \inheritanchor[from={circle}]{base west}%
  \inheritanchor[from={circle}]{base east}%
  \inheritanchor[from={circle}]{north west}%
  \inheritanchor[from={circle}]{south west}%
  \inheritanchor[from={circle}]{north east}%
  \inheritanchor[from={circle}]{south east}%
  \inheritanchorborder[from={circle}]%
  %
  % Only the background path is different
  %
  \backgroundpath{%
    % First the existing 'circle' code:
    \pgfutil@tempdima=\radius%
    \pgfmathsetlength{\pgf@xb}{\pgfkeysvalueof{/pgf/outer xsep}}%
    \pgfmathsetlength{\pgf@yb}{\pgfkeysvalueof{/pgf/outer ysep}}%
    \ifdim\pgf@xb<\pgf@yb%
      \advance\pgfutil@tempdima by-\pgf@yb%
      \pgfutil@tempdimb=\pgfutil@tempdima%
    \else%
      \advance\pgfutil@tempdima by-\pgf@xb%
      \pgfutil@tempdimb=\pgfutil@tempdima%
    \fi%
    \pgfpathcircle{\centerpoint}{\pgfutil@tempdima}%
    %
    % Now the outer rectangle
    \pgfmoveto{\pgfpointadd{\centerpoint}{\pgfpoint{-\pgfutil@tempdima}{-\pgfutil@tempdima}}}%
    \pgflineto{\pgfpointadd{\centerpoint}{\pgfpoint{\pgfutil@tempdima}{-\pgfutil@tempdima}}}%
    \pgflineto{\pgfpointadd{\centerpoint}{\pgfpoint{\pgfutil@tempdima}{\pgfutil@tempdima}}}%
    \pgflineto{\pgfpointadd{\centerpoint}{\pgfpoint{-\pgfutil@tempdima}{\pgfutil@tempdima}}}%
    \pgflineto{\pgfpointadd{\centerpoint}{\pgfpoint{-\pgfutil@tempdima}{-\pgfutil@tempdima}}}%
  }%
}
\makeatother

\begin{document}
\begin{tikzpicture}
  \node [draw=blue, CircleRectangle, inner sep=1pt] at (2,0) {text};
\end{tikzpicture}
\end{document}
share|improve this answer
    
Polar coordinates would seem an obvious choice for this one ... –  Andrew Stacey Jan 23 '12 at 20:06
    
@AndrewStacey: Yep realized that as I got farther into it, so have noted that under "Further Enhancements". –  Peter Grill Jan 23 '12 at 20:15
    
I saw that and was agreeing wholeheartedly with it! –  Andrew Stacey Jan 23 '12 at 20:25
    
Thanks a lot for the edit, and the great macro. –  Alex Frechette Jan 23 '12 at 20:55
    
@AlexFrechette: Please note that I have updated the code to properly adjust based on where the center of the circle is. The earlier version ignored this, and was just lucky that it appeared to work. –  Peter Grill Jan 24 '12 at 0:51
add comment

You could use the fit library to make a rectangle node sourround a circle. by setting inner sep and outer sep to 0pt you can control the size of the circle with minimum size=xx.

\documentclass{minimal}

\usepackage{tikz}
\tikzset{%
    no sep/.style={inner sep=0pt, outer sep=0pt}
}
\usetikzlibrary{fit}

\begin{document}
\begin{tikzpicture}
    \node (your circle) at (2,1) [no sep, draw, shape=circle, minimum size=1cm] {};
    \node [draw, no sep, fit={(your circle)}] {};
\end{tikzpicture}
\end{document}

result

share|improve this answer
    
Good solution. FYI, I have seen comments here saying to not use the minimal class and instead use article as the minimal class. –  Peter Grill Jan 20 '12 at 17:32
    
@PeterGrill Another solution is to use the shapes library with regular polygon option. See the example in the manual. –  percusse Jan 20 '12 at 19:05
    
@PeterGrill: Thanks I didn’t know that. Do you remember why or where you read this? –  Tobi Jan 21 '12 at 10:15
    
@Tobi: MartinScharrer has mentioned this on several posts here, but don't have a link to one and don't know how to search just for comments on a user. –  Peter Grill Jan 23 '12 at 18:04
    
@PeterGrill: OK, Thank’s. I’ll wait till I find it too … :-) –  Tobi Jan 23 '12 at 22:36
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.