Created
June 29, 2016 14:29
-
-
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.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
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