# Tangent Polygon Extensions

Draw something that looks like this:

In more precise terms, draw a circle of radius r, with n evenly-spaces tangent lines of length l. Connect the ends of these lines to form a new n-sided regular polygon.

## Rules

n = number of tangent lines - must be evenly spaced around circle (n>=3)
l = side length of tangent lines

Create a program that accepts the arguments { r, n, l } and draws the required output.

Units are in pixels.

There is no restrictions to the location of the drawing, as long as all of it is visible.

The picture is pretty self-explanatory.

This is code-golf, so shortest code in bytes wins!

• I assume n will be >= 3, is there a maximum? Do you want the tangents and circle as well? Commented Oct 1, 2014 at 2:38
• Yes, n>=3, (intersection in ok if l is not long enough). You should draw the circle and tangents. I think the maximum is basically when the output is a shaded circle. In other words, the maximum is the realistic maximum for a drawing like this. Commented Oct 1, 2014 at 2:43
• Do the pixel units even apply if we produce a vector graphic? Because in such a case pixels are actually quite ill-defined. Or do we have to produce rasterised graphics? Commented Oct 1, 2014 at 9:20
• @MartinBüttner, you may ignore the pixel unit with your (fancy) vector graphics if there is some sort of scale (like an axis). Commented Oct 1, 2014 at 11:13

## T-SQL 440 483

Not going to win any prizes with this one, but I like drawing pictures :)

Edit Expletive! Just noticed I messed up for polygons drawn across the circle. Fixed at a cost.

SELECT Geometry::UnionAggregate(Geometry::Point(0,0,0).STBuffer(@r).STExteriorRing().STUnion(Geometry::STGeomFromText(CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0))).STUnion(Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing())p FROM(SELECT RADIANS(360./@*N)a,RADIANS((360./@*N)-90)b FROM(SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N FROM sys.types a,sys.types b)t)r


Executed with the following variables

declare @r float = 1.0
declare @ int = 10
declare @l float = 3.0


Run in Sql Server Management Studio 2012+ it will return the following in the spatial results tab.

With

declare @r float = 1.0
declare @ int = 360
declare @l float = 3.0


with

declare @r float = 10.0
declare @ int = 3
declare @l float = 10.0


Expanded out

SELECT Geometry::UnionAggregate(    --group together lines
Geometry::Point(0,0,0)          --Set origin
.STBuffer(@r)                   --Buffer to @r
.STExteriorRing()               --Make it a line
.STUnion(                       --Join to the floowing tangent
Geometry::STGeomFromText(   --Create a tangent line
CONCAT('LINESTRING(',@r*SIN(a),' ',@r*COS(a),',',@r*SIN(a)+@l*SIN(b),' ',@r*COS(a)+@l*COS(b),')'),0)
)
).STUnion( --Generate polygon around exterior points
Geometry::ConvexHullAggregate(Geometry::Point(@r*SIN(a)+@l*SIN(b),@r*COS(a)+@l*COS(b),0)).STExteriorRing()
)
p
FROM(
FROM(                           --make enough rows to draw tangents
SELECT TOP(@)row_number()OVER(ORDER BY(SELECT\))-1N
FROM sys.types a,sys.types b
)t
)r


# Python, 133 bytes

The only answer so far to comply with the "Units are in pixels" rule...

from turtle import*
c=circle
r,n,l=input()
lt(90)
exec'c(r,360/n);fd(l);bk(l);'*n
fd(l)
lt(towards(-r,0)-180)
c(distance(-r,0),360,n)


Add exitonclick() to the end if you don't want the window to close immediately.

### Output:

python tangentpoly.py <<< "20, 6, 30":

python tangentpoly.py <<< "100, 8, 200":

• for i in n*[0]:c(r,360/n);fd(l);bk(l) -> exec'c(r,360/n);fd(l);bk(l)'*n; Commented Oct 1, 2014 at 12:20
• Try it online Commented Sep 16, 2016 at 20:29

## Mathematica, 135132131 123 bytes

{r,n,l}=Input[];Graphics[{{0,0}~Circle~r,Line[Join@@Array[{b=(a=r{c=Cos[t=2Pi#/n],s=Sin@t})-l{s,-c},a,b}&,n+1]]},Axes->1>0]


This code expects the input (via a prompt) exactly as specified in the question: e.g. {100, 6, 150}. It produces a vector graphic, so I'm including an axis, as specified in the comments by the OP.

Both the tangents and the polygon are actually a single line strip, by traversing "polygon-corner, tangent point, polygon-corner, next polygon-corner, tangent point, polygon-corner..."

If it wasn't for the axis, I could even do this in 107 bytes:

{r,n,l}=Input[];Graphics@{Circle[],Line[Join@@Array[{b=(a={c=Cos[t=2Pi#/n],s=Sin@t})-l/r{s,-c},a,b}&,n+1]]}


Additional savings (apart from Axes->1>0) come from the fact that I can now rescale everything by r, which simplifies the call to Circle yielding a unit circle.

• {0,0}~Circle~r Commented Oct 1, 2014 at 16:59
• @DavidCarraher heh, I had actually already done that in the 135 bytes, but forgot to copy it back into my notebook, so it got reverted when I made the Unicode change. thanks! Commented Oct 1, 2014 at 17:00

# MATLAB - 233 bytes

function C(n,r,l),t=2*pi/n;c=cos(t);s=sin(t);M=[c,s;-s,c];F=@(y)cell2mat(arrayfun(@(x){M^x*y},1:n));P=F([0;r]);Q=F([l;r]);v='k';t=1e3;t=2*pi/t*(0:t);R=[1:n 1];q=Q(1,R);s=Q(2,R);plot(r*cos(t),r*sin(t),v,[P(1,R);q],[P(2,R);s],v,q,s,v);


Sample function output for n = 8, r = 4, l = 6 (axes included to indicate unit length):

Sample function output for n = 1024, r = 4, l = 2:

• I'm nit-picking, but Units are in pixels Commented Oct 1, 2014 at 4:37
• @DigitalTrauma: Ah. Didn't notice that. MATLAB figures don't have fixed units; they scale to the window. And it's a moot point anyway. Your LOGO based solution in Python has mine soundly beat. Before today I wouldn't have conceived somebody would port LOGO into Python, but there it is. I'm learning as I go along. :P
– COTO
Commented Oct 1, 2014 at 4:53
• Well +1 anyway :) Commented Oct 1, 2014 at 5:01
• The image is almost aperture's logo. Commented Oct 1, 2014 at 5:27

# HTML + JavaScript (E6) 298

To test, save as an html file and open with FireFox. Insert the parameters r,n,l into the input field, comma separated, then tab out.

Or try jsfiddle

<input onblur="
[r,n,l]=this.value.split(','),
z=r-~l,t=D.getContext('2d'),w='lineTo',
D.width=D.height=z*2,
t.arc(z,z,r,0,7);
for(C=1,S=i=0;i++<n;)
t[w](x=z+r*C,y=z+r*S),
t[w](x-l*S,y+l*C),
C=Math.cos(a=6.283*i/n),
S=Math.sin(a),
t[w](z+r*C-l*S,z+r*S+l*C);
t.stroke()">
<canvas id=D>


Sample output