Skip to content

Instantly share code, notes, and snippets.

@matthew-n
Created June 29, 2016 14:29
Show Gist options
  • Save matthew-n/165c9aa2c84ed2a23d37877748a9a8d2 to your computer and use it in GitHub Desktop.
Save matthew-n/165c9aa2c84ed2a23d37877748a9a8d2 to your computer and use it in GitHub Desktop.
A T-SQL implementation of Sierpinski's Triangles, just to see if I could do it.
/*
Description: A T-SQL implementation of Sierpinski's Triangles, just to see if I could do it.
Requires: SQL Server 2012
Inspired by: Alastair Aitchison SQLCLR implementation http://alastaira.wordpress.com/2012/03/06/drawing-fractals-with-sql-server-spatial/
Author: Matthew Naul
*/
DECLARE
@itrations INT = 12,
@seed geometry = geometry::STGeomFromText ('LINESTRING (9 12, 0 0, 18 0, 9 12)',0);
WITH SierpinskiTriangle(lvl,[Ax],[Ay],[Bx],[By],[Cx],[Cy], shape) AS (
SELECT
1 lvl,
base.[Ax], base.[Ay],
base.[Bx], base.[By],
base.[Cx], base.[Cy],
CONCAT('MULTIPOLYGON( (( ', [Ax],' ',[Ay],',',
[Bx],' ',[By],',',
[Cx],' ',[Cy],',',
[Ax],' ',[Ay],')) )') as shape
FROM (
SELECT
@seed.STPointN(1).STX as [Ax], @seed.STPointN(1).STY as [Ay],
@seed.STPointN(2).STX as [Bx], @seed.STPointN(2).STY as [By],
@seed.STPointN(3).STX as [Cx], @seed.STPointN(3).STY as [Cy]
) AS base
UNION ALL
SELECT
itr.lvl+1 AS lvl,
new.[Ax], new.[Ay],
new.[Bx], new.[By],
new.[Cx], new.[Cy],
CONCAT('MULTIPOLYGON( (( ', new.[Ax],' ',new.[Ay],',',
new.[Bx],' ',new.[By],',',
new.[Cx],' ',new.[Cy],',',
new.[Ax],' ',new.[Ay],')) )') as shape
FROM SierpinskiTriangle AS itr
CROSS APPLY(
SELECT
(itr.[Bx] + itr.[Cx]) * .5 as [A0x], (itr.[By] + itr.[Cy]) *.5 as [A0y],
(itr.[Cx] + itr.[Ax]) * .5 as [B0x], (itr.[Cy] + itr.[Ay]) *.5 as [B0y],
(itr.[Ax] + itr.[Bx]) * .5 as [C0x], (itr.[Ay] + itr.[By]) *.5 as [C0y]
) AS mid
CROSS APPLY(
SELECT 1, itr.[Ax] , itr.[Ay] , mid.[C0x], mid.[C0y], mid.[B0x], mid.[B0y] UNION ALL
SELECT 2, mid.[C0x], mid.[C0y], itr.[Bx] , itr.[By] , mid.[A0x], mid.[A0y] UNION ALL
SELECT 3, mid.[B0x], mid.[B0y], mid.[A0x], mid.[A0y], itr.[Cx] , itr.[Cy]
) AS new(number, [Ax], [Ay], [Bx], [By], [Cx], [Cy])
WHERE
([A0x] > .00001 ) and --triagnel with inside geometry type error. Too small, bail
itr.lvl < @itrations
)
SELECT
sys.GeometryUnionAggregate(geometry::STMPolyFromText(shape,0))
FROM
SierpinskiTriangle
WHERE
lvl = @itrations
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment