18

I am trying to draw a square with lines behind a disc going off in all directions. Like a rising sun illustration. There must be better procedures that code this than calculating the coordinates of a circle with \usetikzlibrary{calc} while using that in a \foreach loop for the path ends coordinates and then cropping ...

Draw this

Here is my own constructive procedure. Instead of calculating or clipping a loop steps around a square naming outer nodes. Then another loops draws a path which originates from an off center point to each name. So no clipping needed.

\documentclass[tikz,border=16mm]{standalone}
\def\nodings(#1){%
    \foreach \x in {1,...,#1} {\foreach \y in {1,#1} {\node (noding\x-\y) at (\x,\y) {x};}}%
    \foreach \y in {1,...,#1} {\foreach \x in {1,#1} {\node (noding\x-\y) at (\x,\y) {x};}}%
    }
\def\outrays(#1,#2){%
    \foreach \x in {1,...,#1} {\foreach \y in {1,#1} {\draw[line width=1pt,rounded corners=48pt,line cap=round,bend left=24](#2,#2) to (noding\x-\y);}}%
    \foreach \y in {1,...,#1} {\foreach \x in {1,#1} {\draw[line width=1pt,rounded corners=48pt,line cap=round,bend left=24](#2,#2) to (noding\x-\y);}}%
    }
\begin{document}\begin{tikzpicture}
    \nodings(36)\outrays(36,24)
    \node[circle,fill=white,text=cyan!50!black,text width=192mm] (mydisc) at (24,24) {\fontsize{128}{1}\selectfont NAME\\TITLE};
\end{tikzpicture}\end{document}

EDIT: in the end five procedures exist to construct this picture.

6
  • 1
    @egreg said as much. But also see that the calc package won't calculate TikZ coordinates, for that you need \usetikzlibrary{calc} also perhaps a look at polar coordinates could help. Oct 25, 2016 at 8:14
  • 1
    I was thinking there is a way to wing it without using calc at all even. Just creating a for loop that places steps around a square as nodes, then just a for loop that draws a path to each node. A square in steps can be drawn with a for loop. No calc needed at all. More efficient? The nodes would be invisible. Then no cropping needed. Oct 25, 2016 at 8:16
  • 1
    @GuidoJorg TikZ can crop.
    – egreg
    Oct 25, 2016 at 8:18
  • @GuidoJorg, will the circle be at the Center of the square of arbitray Position? Oct 25, 2016 at 8:24
  • 1
    suggestion: change your edge labels to (noding\x-\y) such as to avoid overwriting node12-3 with node1-23, which would result in missing rays in your solution.
    – Eva
    Oct 25, 2016 at 19:56

4 Answers 4

14

To connect the edges of the circle you can use the border anchors of nodes (A.120) and the to Operator to connect it to the outer square.

\documentclass[tikz, border=5mm]{standalone}

\begin{document}
\begin{tikzpicture}
\draw[clip] (-2,-2) rectangle +(3,3);
\node[minimum size=5cm](A){};
\node[circle, draw, minimum size=1cm](B) at (A.center) {};
\foreach \angle in {0,5,...,360} \draw (B.\angle) to (A);
\end{tikzpicture}
\end{document}

The thing is if the circle B is not centered at the square A some strange thing happens which I don't know why but there's probably a reason. That's why there's the \draw[clip] there.

enter image description here

3
  • I'll see what can be done but to do so with the current solution doesn't seem too easy because of the clip command... Could you share the purpose of this nodes? Perhaps there's another way to do the same thing. Oct 25, 2016 at 9:54
  • the border intersection is calculated by the target point and the node center. When this distance is negative the angle (target point is inside the borders) is still calculated as is. Hence everything bundles up towards the corner the target is shifted to,
    – percusse
    Oct 25, 2016 at 20:52
  • No need to change the solution. I was just looking to learn all the different possible ways to make such an image. Total of five ways now. Oct 25, 2016 at 21:50
18

You don't need to connect nodes.

First draw background lines. All starting from (0,0).

\foreach \angle in {0,1,...,359} \draw[cyan!50!black] (0,0)--++(\angle:4);

enter image description here

Second, draw a circular node white filled:

\node[circle, fill=white, text=cyan!50!black, text width=15mm, align=center]{Orion\\2000};

enter image description here

And third (although it's the first command), define the clipping area:

\documentclass[tikz, border=5mm]{standalone}

\begin{document}
\begin{tikzpicture}
\path[clip] (-2.5,-3) rectangle (1.3,1.5);
\foreach \angle in {0,1,...,359} \draw[cyan!50!black] (0,0)--++(\angle:4);
\node[circle, fill=white, text=cyan!50!black, text width=15mm, align=center]{Orion\\2000};
\end{tikzpicture}
\end{document}

enter image description here

Update:

As it seems that OP doesn't want to use a clip and wants to define explicit points onto an external rectangle, here you have another solution. It's based on the linked one, but instead of named nodes, it uses calc library:

\documentclass[tikz,border=16mm]{standalone}
\usetikzlibrary{calc}

\begin{document}
\begin{tikzpicture}
    \node[minimum size=36cm, anchor=south west] (A) {};
    \foreach \j [remember=\j as \lastj (initially north west)] in {north east, south east, south west, north west}{
        \foreach \i in {0,1,...,36}
            \draw[line width=1pt, bend left=24, draw=cyan!50!black] (24,24) to ($(A.\lastj)!\i/36!(A.\j)$);
    }
    \node[circle,fill=white,text=cyan!50!black,text width=192mm, align=center] (mydisc) at (24,24) {\fontsize{128}{1}\selectfont NAME\\TITLE};
\end{tikzpicture}
\end{document}

enter image description here

2
  • 1
    but this looks different ... a basic decision is: do you want equal angles of your arrays (makes a "sun rays" way graph, use polar coordinates / angle definitions), or do you want equal distant points on the edges (results in grouped rays as above, if not in the exact center of the graph - not so nice ...)
    – Eva
    Oct 25, 2016 at 20:01
  • 1
    @Eva I know that the second solution is different from first. In this case I just wanted to show that it was possible to build Guido's solution without having to define all those nodes equally distributed along the rectangle. For "sun rays" use first solution, for "equally distributed end points on a rectangle" use the second.
    – Ignasi
    Oct 25, 2016 at 22:13
5

Still version

\documentclass[preview,pstricks,margin=5mm]{standalone}
\usepackage{pst-node}
\begin{document}
\begin{pspicture}(-5,-5)(5,5)
    \psclip{\psframe[linestyle=none,linewidth=0](-5,-5)(5,5)}
        \pnode(1,1){A}\pscircle(A){2}
        \foreach \i in {0,10,...,350}{\pnode[A](2;\i){B}\psline(B)([nodesep=10]{B}A)}
    \endpsclip
\end{pspicture}
\end{document}

enter image description here

Animated version

\documentclass[preview,pstricks,margin=5mm]{standalone}
\usepackage{pst-node}

\def\pict(#1){\begin{pspicture}(-5,-5)(5,5)
    \psclip{\psframe[linestyle=none,linewidth=0](-5,-5)(5,5)}
        \pnode(#1){A}\pscircle(A){2}
        \foreach \i in {0,10,...,350}{\pnode[A](2;\i){B}\psline(B)([nodesep=10]{B}A)}
    \endpsclip
\end{pspicture}}

\begin{document}
\foreach \j in {0,20,...,340}{\pict(1;\j)}
\end{document}

enter image description here

4

If you want to avoid clipping (although I'm not sure why you'd want to do that) you can use intersections instead:

\documentclass[tikz, border=1mm]{standalone}
\usetikzlibrary{intersections}
\begin{document}
\begin{tikzpicture}
\path[name path=rect] (-2,-2) rectangle +(3,3);
\node[circle, minimum size=1cm] (A) at (0,0) {};
\foreach \angle in {0,3,...,359}{
  \begin{pgfinterruptboundingbox}
    \path[name path global=ray] (A.\angle) to ++ (\angle:10);
  \end{pgfinterruptboundingbox}
  \draw[name intersections={of=rect and ray}] (A.\angle) to (intersection-1);
}
\end{tikzpicture}
\end{document}

enter image description here

2
  • The reason behind avoiding clip is to have a node name at the end of each line (at the square region). The purpose of having these node names is yet unknown... Oct 25, 2016 at 22:28
  • Ah, well this version definitely allows for that.
    – Emma
    Oct 25, 2016 at 22:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .