I have revised the Manifold 9 query posted above. The differences are - A 1.8x speedup. This is mainly due to drawing the hexagon cell only once (nominally at (0, 0)), then using GeomShift() to copy it to every grid position. (The previous version drew a new geom at every grid position.) There is some other tuning as well.
- I've fixed some bugs that meant the AOI would usually be slightly over-filled around the edges.
- Improved readability, through better use of named values and better notes.
As noted inthis thread, the next job is to improve the query so that it can efficiently fill an irregular AOI, rather than always filling the whole bounding box of all objects.
--SQL9 -- source drawing and table VALUE @drawing TABLE = [Drawing]; VALUE @table TABLE = [Drawing Table]; -- output drawing and table -- comment out if table and drawing do not already exist -- (else "invalid entity type") DROP TABLE [Hex grid Table]; DROP DRAWING [Hex grid]; -- set hex cell size by circumradius VALUE @circumradius FLOAT64 = 1; -- distance from cell centre to a vertex -- equals length of sides (equilateral triangles) VALUE @apothem FLOAT64 = @circumradius * Cos(30 * PI / 180); -- distance from cell centre to midpoint of a side VALUE @height FLOAT64 = @apothem * 2; -- row height (equals cell height) VALUE @width FLOAT64 = 3 * @circumradius / 2; -- column width (less than cell width since interleaved) -- convenience functions to rename result fields FUNCTION xindex(@xlimit INT32) TABLE AS ( SELECT [Value] AS [xindex] FROM (TABLE CALL ValueSequence(0, @xlimit, 1)) ) END; FUNCTION yindex(@ylimit INT32) TABLE AS ( SELECT [Value] AS [yindex] FROM (TABLE CALL ValueSequence(0, @ylimit, 1)) ) END; CREATE TABLE [Hex grid Table] ( [mfd_id] INT64, [xindex] INT32, [yindex] INT32, [Geom] GEOM, INDEX [mfd_id_x] BTREE ([mfd_id]), INDEX [Geom_x] RTREE ([Geom]), PROPERTY 'FieldCoordSystem.Geom' ComponentCoordSystem(@drawing) ); CREATE DRAWING [Hex grid] ( PROPERTY 'FieldGeom' 'Geom', PROPERTY 'Table' '[Hex grid Table]', PROPERTY 'StyleAreaColorBack' '{ "Value": -16777216 }' -- transparent fill ); INSERT INTO [Hex grid Table] ([xindex], [yindex], [Geom]) SELECT --[mfd_id], -- handled automatically [xindex], [yindex], GeomShift([Cell], VectorMakeX2([xcentre], [ycentre])) -- GeomShift does not benefit from multiple threads -- (if it did we should move it from the transport layer) FROM ( SELECT [xindex], [yindex], -- draw hex cell nominally centred at (0, 0) -- vertex order -- 1 2 -- 0 + 3 -- 5 4 GeomConvertToArea( GeomConvertToPoint( -- pro forma to combine branches INLINE GeomMergePoints( GeomMakePoint(VectorMakeX2( -@circumradius, 0 )), GeomMakePoint(VectorMakeX2( -@circumradius / 2, @apothem )), GeomMakePoint(VectorMakeX2( @circumradius / 2, @apothem )), GeomMakePoint(VectorMakeX2( @circumradius, 0 )), GeomMakePoint(VectorMakeX2( @circumradius / 2, -@apothem )), GeomMakePoint(VectorMakeX2( -@circumradius / 2, -@apothem )), GeomMakePoint(VectorMakeX2( -@circumradius, 0 )) -- first point repeated ), FALSE -- combine branches ) ) AS [Cell], -- list cell centres [xmin] + [xindex] * @width AS [xcentre], [ymin] + [yindex] * @height + (@height / 2) * [xindex] MOD 2 AS [ycentre] -- odd columns offset upwards by half cell height (equals apothem) FROM ( SELECT [xmin], [ymin], --[ymax], [xindex], -- splitting by yindex as an extra step, after xindex is known -- to allow for cases where cell height subdivides the AOI bounds exactly SPLIT CALL yindex( -- for even columns, round up to ensure the top row of cells is not missing -- for odd columns, round normally to prevent an extra row of cells above bounds CASE [xindex] MOD 2 WHEN 0 THEN Ceil(([ymax] - [ymin] - @height / 2) / @height) -- even column WHEN 1 THEN Round(([ymax] - [ymin] - @height / 2) / @height) -- odd column END -- alternative -- reduce the range for odd columns by an extra half cell height (and round up) --Ceil(([ymax] - [ymin] - (@height / 2) * (1 + [xindex] MOD 2)) / @height) ) --> [yindex] FROM ( SELECT [xmin], --[xmax], [ymin], [ymax], SPLIT CALL xindex(Ceil(([xmax] - [xmin] - @width / 2) / @width)) --> [xindex] FROM ( SELECT VectorValue([box], 0) AS [xmin], VectorValue([box], 1) AS [ymin], VectorValue([box], 2) AS [xmax], VectorValue([box], 3) AS [ymax] FROM ( SELECT GeomUnionRects(GeomBoundsRect( CASE GeomIsPoint([Geom]) WHEN TRUE THEN GeomConvertToLine([Geom]) ELSE [Geom] END )) AS [box] -- common bounding box of all geoms (FLOAT64X4) FROM @table --FROM CALL Selection(@table, TRUE) THREADS SystemCpuCount() DIV 2 ) THREADS 1 ) THREADS 1 ) THREADS 1 ) --THREADS 1 THREADS SystemCpuCount() DIV 2 + 1 ) THREADS 1 ; Attachments: Draw hex grid m9 i.sql
|