19

triangles inside triangle

How to draw rotated triangles inside triangles as shown above? I know how to draw a triangle; But not able to draw that. I found a similar example from https://latexdraw.com/tikz-shapes-triangle/

\documentclass[border=0.2cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\begin{document}

\begin{tikzpicture}[thick,violet] 
\foreach \i in {-30,-28,...,0}{

\node[draw,
    fill=violet!10,
    isosceles triangle,
    isosceles triangle apex angle=60,
    minimum size=-2*\i mm, 
    rotate=\i,inner sep =0pt] at (0,0){};
}

\end{tikzpicture}

\end{document}
1
16

A simple solution with not too much calculation. Just place new vertices at \p% of the previous edge, and then draw.

rotation pattern

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

\begin{document}

\def\n{15}      % Number of triangles
\def\r{3}       % Radius of the larger triangle
\def\p{20}      % Percentage for positioning the next vertex on the edge
\def\col{violet}

    \begin{tikzpicture}
        \path (90:\r)  coordinate(A)
              (210:\r) coordinate(B)
              (330:\r) coordinate(C);
        \draw[\col,fill=\col!20] (A) -- (B) -- (C) -- cycle;
        \foreach \x in {1,...,\n}{%
            \path (A) coordinate(M);
            \path (A) -- (B) coordinate[pos=\p/100](A)
                      -- (C) coordinate[pos=\p/100](B)
                      -- (M) coordinate[pos=\p/100](C);
            \draw[\col,fill=\col!20] (A)--(B)--(C)--cycle;
        }
    \end{tikzpicture}
\end{document}
2
  • When I tried with \def\n{0} , I get two triangles. Am I wrong? Sep 15 at 14:25
  • If you define n to 0, you then try to make a loop from 1 to 0. Issues occur when you do that. Note that n is the number of inner triangles, the larger one is drawn before the loop. It is highly customizable, then, even to draw a higher order regular polygon, for example.
    – SebGlav
    Sep 15 at 14:28
16

In Metapost you can define a general transform operation by equating any three non-co-linear points. This is wrapped up in luamplib so compile it with lualatex.

enter image description here

\documentclass{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
beginfig(1);
    numeric s; s = 1/8;
    for n=3 upto 5:
        path t; t = for i=0 upto n-1: 100 up rotated (360/n*i) -- endfor cycle;
        transform r;
        for i=0 upto 2:
            point i of t transformed r = point i + s of t;
        endfor
        picture P; P = image(
            for i=1 upto floor (n/s):
                draw t;
                fill t withcolor (i * s / n)[white, blue];
                t := t transformed r;
            endfor
        );
        draw P shifted (200n, 0);
    endfor
endfig;
\end{mplibcode}
\end{document}

Borrowing the scaling calculation from one of the other solutions, you could also do this with MP's zscaled operator. Here is an alternative that allows you more easily to control the angle of rotation a and the number of turns N.

\documentclass{standalone}
\usepackage{luamplib}
\begin{document}
\begin{mplibcode}
beginfig(1);
    numeric a, N; a = 12; N = 7;
    for n=3 upto 5:
        path t; t = for i=0 upto n-1: 100 up rotated (360/n*i) -- endfor cycle;
        numeric b, c; c = 180 - 360/n; b = 180 - c - a;
        pair r; r = dir a scaled (sind(c) / (sind(a) + sind(b)));
        picture P; P = image(
            for i=1 upto N:
                draw t;
                fill t withcolor (i / 2N)[white, blue];
                t := t zscaled r;
            endfor
        );
        draw P shifted (200n, 0);
    endfor
endfig;
\end{mplibcode}
\end{document}

Here I have set the turn angle to 12° and the number of turns to 7. Note: In order to make the calculations work as expected, you need to keep the turn angle in the range 0 < a < 360/n.

Compile the second example with lualatex to get this:

enter image description here

If you want to learn more about Metapost, then you can find tutorials and examples on the MP page at Tug.

Explanations

Here is an explanation of how the scaling works, and why it generalizes to polygons with more sides.

enter image description here

For a given angle of rotation α, the original polygon with sides of length a+b needs to be scaled down to one with sides of length c. So the required scaling ratio is c/(a+b). You can't measure the lengths, but you can measure the angles: α is given; γ is 180-360/n where n is the number of sides; and β is 180-α-γ.

The Law of Sines tells us that

sin α / a = sin β / b = sin γ / c = x

hence

ax = sin α, bx = sin β, and cx = sin γ

so the required scaling ratio can be expressed using the sines

c/(a+b) = cx / (ax+bx) = sin γ / (sin α + sin β)

and as you can see from the diagram this works for any regular polygon where n>2.

4
  • Please can you be more precise and cite the solution post ;) .Good job for the generalization to the 4 and five sides polygons. Sep 16 at 10:09
  • I am not quite sure what you mean by "cite the solution post" ? If you mean "how can you adapt my example so that it draws exactly what you posted", then try reducing a to 10 and removing the fill t... line. All of my examples are only supposed to be starting points for your own experiments!
    – Thruston
    Sep 16 at 10:28
  • Sorry but what I mean is it would be more helpful for the post readers to know exactly which post you reference to with "Borrowing the scaling calculation from one of the other solutions,..." Sep 16 at 10:38
  • 1
    OK will do, thanks.
    – Thruston
    Sep 16 at 10:41
14

with tikz

\documentclass{article}
\usepackage{xfp}
\usepackage{tikz}
\usetikzlibrary{calc}
\begin{document}
\begin{tikzpicture}
\pgfmathsetmacro{\sca}{0.85} % scale
\pgfmathsetmacro{\nt}{7} % number of triangles
\coordinate (A1) at (0,0);
\coordinate (B1) at (5,0);
\coordinate (C1) at (60:5);
\draw (A1) -- (B1) -- (C1) -- cycle;

\foreach \x in {2,...,\nt} {
    \coordinate (A\x) at ($(A\fpeval{\x-1})!\fpeval{1-\sca}!(B\fpeval{\x-1})$);
    \coordinate (B\x) at ($(B\fpeval{\x-1})!\fpeval{1-\sca}!(C\fpeval{\x-1})$);
    \coordinate (C\x) at ($(C\fpeval{\x-1})!\fpeval{1-\sca}!(A\fpeval{\x-1})$);
    \draw (A\x) -- (B\x) -- (C\x) -- cycle;
}
\end{tikzpicture}
\end{document}

enter image description here

1
  • 2
    To elucidate on @polyn's answer, the secret here is not to think of this as rotations, but rather in terms of what's happening geometrically. Each iteration of the triangle has its vertices at some fixed proportion of the line segment between the vertices of the enclosing triangle. Thinking of the problem in mathematical terms always helps with TikZ
    – Don Hosek
    Sep 15 at 13:33
13

With triangle nodes as in the OP MWE: and with the help of the math tikzlibrary

The idea is to rotate and downscale appropriately all the triangles. It can be found that the scale factor s and the rotation angle a are related by:

s=sin(60) / ( sin(120-a) + sin a)

\documentclass[border=0.2cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric,math}

\begin{document}

\begin{tikzpicture}[violet] 

\tikzmath{
\dangle=15; % angle variation  between two successive triangles
\scale=(sin(60)/(sin(120-\dangle)+sin(\dangle)); % reduction factor of the triangle sides (from elementary geometry)
\a=50;  % the size of the wider triangle
}


\foreach \i in {0,...,5}{ % (5+1) triangles to draw

\node[draw,line join=round,
    fill=violet!10,
    regular polygon,
    regular polygon sides=3,
    minimum size=\a*(\scale)^\i , 
    rotate=\i*\dangle,
    inner sep =0pt] at (0,0){};
}

\end{tikzpicture}
\end{document}

enter image description here

2
  • Interesting use of calculation too!
    – SebGlav
    Sep 15 at 14:29
  • Apologies for stealing your calculation idea in my second solution...
    – Thruston
    Sep 16 at 9:53
12

Just another trivial solution with PSTricks for either fun or comparison purposes.

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-calculate,pst-node,multido}
\begin{document}
\begin{pspicture}(10,\pscalculate{5*sqrt(3)})
\pnodes{P}(0,0)(10,0)(10;60)
\psnpolygon(0,\Pnodecount){P}
\foreach \i in {1,2,...,10}
{
    \nodexn{.75(P0)+.25(P1)}{Q0}
    \nodexn{.75(P1)+.25(P2)}{Q1}
    \nodexn{.75(P2)+.25(P0)}{Q2}
    \pspolygon(Q0)(Q1)(Q2)
    \nodexn{Q0}{P0}
    \nodexn{Q1}{P1}
    \nodexn{Q2}{P2}
}
\end{pspicture}
\end{document}

enter image description here

Animated version

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-calculate,pst-node,multido}
\begin{document}
\foreach \N in{0,1,2,...,50}{%
\begin{pspicture}(10,\pscalculate{5*sqrt(3)})
\pnodes{P}(0,0)(10,0)(10;60)
\psnpolygon(0,2){P}
\psLoop{\N}
{
    \foreach \i in {0,1,2}{\nodexn{.95(P\i)+.05(P\pscalculate{1+5*\i/2-3*\i^2/2})}{Q\i}}
    \foreach \i in {0,1,2}{\nodexn{Q\i}{P\i}}
    \psnpolygon(0,2){P}
}
\end{pspicture}}
\end{document}

enter image description here

General Solution

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node,pst-plot}

\def\R{5}% radius
\def\M{60}% number of children

\begin{document}
\foreach \N  in {3,4,...,13}{% number of vertices
\degrees[\N]
\pspicture(-\R,-\R)(\R,\R)
\curvepnodes[plotpoints=\numexpr\N+1]{0}{\N\space AnytoRad}{\R*cos(t)|\R*sin(t)}{P}
\psnpolygon(0,\numexpr\N-1){P}
\psLoop{\M}
{
    \foreach \i in {0,1,...,\numexpr\N-1}{\nodexn{.95(P\i)+.05(P\the\numexpr\i+1\relax)}{Q\i}}
    \foreach \i in {0,1,...,\numexpr\N-1}{\nodexn{Q\i}{P\i}}
    \nodexn{P0}{P\N}
    \psnpolygon(0,\numexpr\N-1){P}
}
\rput[rt](\R,\R){$N=\N$}
\endpspicture}
\end{document}

enter image description here

Much More General Solution

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node,pst-plot}
\pstVerb{realtime srand}
\def\R{5}% radius
\def\M{30}% number of children
\let\closedcurve\psnccurve % other option: \psnpolygon
\begin{document}
\foreach \N  in {3,4,...,20}{% number of vertices
\degrees[\N]
\pspicture(-\R,-\R)(\R,\R)
\curvepnodes[plotpoints=\numexpr\N+1]{0}{\N\space AnytoDeg}{Rand neg 3 mul 3 add 3 div \R\space mul t PtoC}{P}
\closedcurve[linecolor=red](0,\numexpr\N-1){P}
\nodexn{P0}{P\N}
\psLoop{\M}
{
    \foreach \i in {0,1,...,\numexpr\N-1}{\nodexn{.85(P\i)+.15(P\the\numexpr\i+1\relax)}{Q\i}}
    \foreach \i in {0,1,...,\numexpr\N-1}{\nodexn{Q\i}{P\i}}
    \nodexn{P0}{P\N}
    \closedcurve(0,\numexpr\N-1){P}
}
\rput[rt](\R,\R){$N=\N$}
\endpspicture}
\end{document}

enter image description here

enter image description here

The Last And Least

\documentclass[pstricks,border=12pt]{standalone}
\usepackage{pst-node,pst-plot}
\pstVerb{realtime srand}
\def\R{5}% radius
\def\M{20}% number of children
\let\closedcurve\psnpolygon % other option: \psnpolygon
\begin{document}
\foreach \N  in {3,4,...,40}{% number of vertices
\degrees[\N]
\pspicture[showpoints](-\R,-\R)(\R,\R)
\curvepnodes[plotpoints=\numexpr\N+1]{0}{\N\space AnytoRad}{\R*sin(t)^3|\R*(13*cos(t)-5*cos(2*t)-2*cos(3*t)-cos(4*t))/16+1/2}{P}
\closedcurve[linecolor=red](0,\numexpr\N-1){P}
\nodexn{P0}{P\N}
\psLoop{\M}
{
    \foreach \i in {0,1,...,\numexpr\N-1}{\nodexn{.9(P\i)+.1(P\the\numexpr\i+1\relax)}{Q\i}}
    \foreach \i in {0,1,...,\numexpr\N-1}{\nodexn{Q\i}{P\i}}
    \nodexn{P0}{P\N}
    \closedcurve[strokeopacity=.5](0,\numexpr\N-1){P}
}
\rput[rt](\R,\R){$N=\N$}
\endpspicture}
\end{document}

enter image description here

1
10

Only for comparison, compile with Asymptote.

In all my examples, s is a scale.

A similar code of Thruston's answer.

size(300);
real s=1/8;
for (int m=3; m<=5; ++m){
  path[] a={polygon(m)};
  for (int i=1; i<= m/s; ++i){
    pair[] A;
    for (int j=0; j < size(a[i-1]); ++j)
    {
      A[j] = point(a[i-1],j+s);
    }
    a[i]=operator --(... A)--cycle;
  }
  picture P;
  for (int i=0; i<a.length; ++i)
    filldraw(P,a[i],interp(white,blue,(i+1)*s));
  add(shift((2*m,0))*P);
}

enter image description here

Animation:

settings.tex="pdflatex";
import animate;
size(300);
real s=1/8;
animation Ani;

path[] testpolygon(int m)
{
  path[] a={polygon(m)};
  for (int i=1; i<= m/s; ++i){
    pair[] A;
    for (int j=0; j < size(a[i-1]); ++j)
    {
      A[j] = point(a[i-1],j+s);
    }
    a[i]=operator --(... A)--cycle;
  }
  return a;
}
for (int n=3; n<=5; ++n){
  for (int i=0; i<testpolygon(n).length; ++i){
    save();
    filldraw(testpolygon(n)[i],interp(white,blue,(i+1)*s));
    Ani.add();
  }
  erase();
}
erase();
Ani.movie();

enter image description here

Example 1:

unitsize(3cm);

pair A=(0,0),B=(4,0),C=rotate(60,A)*B;
path d=A--B--C--cycle;
int n=15;
path pic(real s=0.2)
{
pair M=A;
A=relpoint(A--B,s);
B=relpoint(B--C,s);
C=relpoint(C--M,s);
return A--B--C--cycle;
}

for (int i=0; i < n; ++i)
{
if (i==0) draw(d,blue);
else draw(pic(0.2),(i%2 == 1) ? red : blue);
}

enter image description here

Example 2:

unitsize(3cm);

pair A=(0,0),B=(4,0),C=(4,4),D=(0,4);
path d=A--B--C--D--cycle;
int n=15;
path pic(real s=0.2)
{
pair M=A;
A=relpoint(A--B,s);
B=relpoint(B--C,s);
C=relpoint(C--D,s);
D=relpoint(D--M,s);
return A--B--C--D--cycle;
}

for (int i=0; i < n; ++i)
{
if (i==0) fill(d,blue);
else fill(pic(0.2),(i%2 == 1) ? red : blue);
}

enter image description here

Example 3:

unitsize(4cm);

path g=polygon(5);
pair A=point(g,0),B=point(g,1),C=point(g,2),D=point(g,3),E=point(g,4);
path d=A--B--C--D--E--cycle;
int n=35;
path pic(real s=0.2)
{
pair M=A;
A=relpoint(A--B,s);
B=relpoint(B--C,s);
C=relpoint(C--D,s);
D=relpoint(D--E,s);
E=relpoint(E--M,s);
return A--B--C--D--E--cycle;
}

for (int i=0; i < n; ++i)
{
if (i==0) fill(d,blue);
else fill(pic(0.2),(i%2 == 1) ? red : blue);
}

enter image description here

Example 4:

size(300);

void testpolygon(pair[] A, int n=3, real s=0.2, pen p1=green, pen p2=magenta)
{
  pair[] a=copy(A);
  guide g= operator --(... a)--cycle;
  guide pic()
  {
    pair M=a[0];
    for (int i=0; i<a.length; ++i)
    {
      if (i != (a.length-1))
      {
        a[i]=relpoint(a[i]--a[i+1],s);
      } else {
        a[i]=relpoint(a[i]--M,s);
      }
    }
    return operator --(... a)--cycle;
  }
  for (int i=0; i <= n; ++i)
  {
    if (i==0) filldraw(g,p1);
      else filldraw(pic(),(i%2==1) ? p2 : p1);
  }
}

int n=25;
path g=rotate(-60)*polygon(6);
testpolygon(new pair[]{(0,0),point(g,0),point(g,1)},n,0.1);
testpolygon(new pair[]{(0,0),point(g,1),point(g,2)},n,0.1);
testpolygon(new pair[]{(0,0),point(g,2),point(g,3)},n,0.1);
testpolygon(new pair[]{(0,0),point(g,3),point(g,4)},n,0.1);
testpolygon(new pair[]{(0,0),point(g,4),point(g,5)},n,0.1);
testpolygon(new pair[]{(0,0),point(g,5),point(g,0)},n,0.1);

enter image description here

The final code:

\documentclass[12pt]{article}
\usepackage[margin=1.5cm]{geometry}
\usepackage[inline]{asymptote}
\usepackage{graphicx}
\usepackage{subcaption} % https://latex-tutorial.com/tutorials/figures/

\begin{document}

In TeXstudio, Options $\rightarrow$ Configure TeXstudio... $\rightarrow$ Build $\rightarrow$ Build \& View is txs:///asy-pdf-chain $\rightarrow$ OK. Then press Build \& View, processing... (Compile two times)

\begin{figure}[h!]
    \centering
    \begin{subfigure}[b]{0.4\linewidth}
        \centering
        \begin{asy}
        unitsize(1.5cm);
        
        pair A=(0,0),B=(4,0),C=rotate(60,A)*B;
        path d=A--B--C--cycle;
        int n=10;
        path pic(real s=0.2)
        {
            pair M=A;
            A=relpoint(A--B,s);
            B=relpoint(B--C,s);
            C=relpoint(C--M,s);
            return A--B--C--cycle;
        }
        
        for (int i=0; i < n; ++i)
        {
            if (i==0) filldraw(d,blue,green+0.8bp);
            else filldraw(pic(0.2),(i%2 == 1) ? red : blue,green+0.8bp);
        }
        \end{asy}
        \caption{Picture 1}
    \end{subfigure}
    \begin{subfigure}[b]{0.4\linewidth}
        \centering
        \begin{asy}
        unitsize(1.25cm);
        
        pair A=(0,0),B=(4,0),C=(4,4),D=(0,4);
        path d=A--B--C--D--cycle;
        int n=10;
        path pic(real s=0.2)
        {
            pair M=A;
            A=relpoint(A--B,s);
            B=relpoint(B--C,s);
            C=relpoint(C--D,s);
            D=relpoint(D--M,s);
            return A--B--C--D--cycle;
        }
        
        for (int i=0; i < n; ++i)
        {
            if (i==0) filldraw(d,blue,green+0.8bp);
            else filldraw(pic(0.2),(i%2 == 1) ? red : blue,green+0.8bp);
        }
        \end{asy}
        \caption{Picture 2}
    \end{subfigure}
    \begin{subfigure}[b]{\linewidth}
        \centering
        \begin{asy}[width=10cm]
        size(300);
        
        void testpolygon(pair[] A, int n=3, real s=0.2, pen p1=green, pen p2=magenta)
        {
        pair[] a=copy(A);
        guide g= operator --(... a)--cycle;
        guide pic()
        {
        pair M=a[0];
        for (int i=0; i<a.length; ++i)
        {
        if (i != (a.length-1))
        {
        a[i]=relpoint(a[i]--a[i+1],s);
        } else {
        a[i]=relpoint(a[i]--M,s);
        }
        }
        return operator --(... a)--cycle;
        }
        for (int i=0; i <= n; ++i)
        {
        if (i==0) filldraw(g,p1);
        else filldraw(pic(),(i%2==1) ? p2 : p1);
        }
        }
        
        int n=25;
        path g=rotate(-60)*polygon(6);
        testpolygon(new pair[]{(0,0),point(g,0),point(g,1)},n,0.1);
        testpolygon(new pair[]{(0,0),point(g,1),point(g,2)},n,0.1);
        testpolygon(new pair[]{(0,0),point(g,2),point(g,3)},n,0.1);
        testpolygon(new pair[]{(0,0),point(g,3),point(g,4)},n,0.1);
        testpolygon(new pair[]{(0,0),point(g,4),point(g,5)},n,0.1);
        testpolygon(new pair[]{(0,0),point(g,5),point(g,0)},n,0.1);
        \end{asy}
    \caption{Picture 3}
\end{subfigure}
\end{figure}
Done!
\end{document}

enter image description here

5
  • Good job! I think you should edit your post to put your code inside a an asy environment in a LaTeX document Sep 15 at 14:44
  • @HafidBoukhoulda Yes, I updated my answer. Sep 15 at 16:49
  • 1
    @Hafid Boukhoulda: Wrapping the asy code inside an asy environment is convenient, only when you need to be sure that asy graphics uses the same font/text settings used in the document. Otherwise this is absolutely optional (unnecessary) step.
    – g.kov
    Sep 16 at 5:43
  • @g.kov. The idea is to have the drawing code within the same file as the text document. And also to make it easy for beginners who don't know yet asymptote to test the answer. Sep 16 at 9:11
  • @Hafid Boukhoulda: On the contrary, especially for beginners, it is usually much easier and potentially less confusing to test a standalone asy code.
    – g.kov
    Sep 16 at 10:58
2

I pay attention to clean coding from this 2008 link to TikZ and Asymptote. For this figure, Asymptote is more comfortable then TikZ, due to handy array operations. opacity makes the picture more 3D.

With Asymptote, just make an array A to store the vertices of the consecutive polygon in a loop. Another array B is for temporary storing; array operations A.push, A.cyclic=true, B=A have natural meaning; operator--(...A)--cycle is for straight joining the polygon path.

enter image description here

unitsize(1cm);
defaultpen(opacity(.5));
int n=3; // number of vertices
real r=3;
real pos=.1;
pair[] A; A.cyclic=true;
for(int i=0; i<n;++i) A.push(r*dir(90+360*i/n));  
filldraw(operator--(...A)--cycle,.1red+.9white);
    
for(int k=1;k<25;++k){
int kcolor=10+5*k;
pen p=kcolor/100*red+(1-kcolor/100)*white;  
pair[] B; B.cyclic=true;
for(int i=0; i<n;++i) B.push(pos*A[i]+(1-pos)*A[i+1]);  
filldraw(operator--(...B)--cycle,p);
A=B;  
}
    
shipout(bbox(5mm,Fill(black)));

With TikZ,

enter image description here

\documentclass[tikz,border=5mm]{standalone}
\pagecolor{green!50}
\begin{document}
\begin{tikzpicture}[fill opacity=.5]
\def\n{5}
\def\r{3}
\def\pos{.2}
\colorlet{mycolor}{purple}
\foreach \i in {1,...,\n} 
\path ({90+360*\i/\n}:\r) coordinate (A\i);

\path (A\n) coordinate (T);
\draw[fill=mycolor!10] (T) foreach \i in {1,...,\n} {--(A\i)};

\foreach \k in {1,2,...,50}{
\pgfmathsetmacro{\kcolor}{10+5*\k}
\path (T) foreach \i in {1,...,\n} 
{--(A\i) coordinate[pos=\pos] (A\i)};

\path (A\n) coordinate (T);
\draw[fill=mycolor!\kcolor] (T) foreach \i in {1,...,\n} {--(A\i)};
}
\end{tikzpicture}
\end{document}
1

https://latexdraw.com/tikz-shapes-triangle/ enter image description here

\documentclass[border=0.2cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{shapes.geometric}

\begin{document}

\begin{tikzpicture}[thick,violet] 
\foreach \i in {-30,-28,...,0}{

\node[draw,
    fill=violet!10,
    isosceles triangle,
    isosceles triangle apex angle=60,
    minimum size=-2*\i mm, 
    rotate=\i,inner sep =0pt] at (0,0){};
}

\end{tikzpicture}

\end{document}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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