### Author Topic: Hyperbolic Tessellation using C# .NET  (Read 2294 times)

0 Members and 1 Guest are viewing this topic.

#### AlexF

• Bull Frog
• Posts: 247
##### Hyperbolic Tessellation using C# .NET
« on: January 13, 2012, 07:20:53 am »
Hi folks,

I'm currently experiencing a dramatic fall-off of workload (through no fault of my own) and have been attempting to get to grips with all-things 3D Printing-related.

One area I'm particularly keen on (because it could save users of these apparatus money in the long-run) is the use of hyperbolic tessellation to create variable-density fill within objects that are due to be 3D Printed using a machine like a Makerbot or UP! 3D Printer.

I've been researching the different methods that might be used to create the tessellation needed to (for instance) create an AutoCAD drawing that encloses a shape similar to those seen on the wikipedia page I linked to above.

I've had  a search around the wider web and this site and (thus far) I can't find any examples of people having does this using .NET.

There are however similar-looking approaches done using AutoLISP:

conic sections in plan view

-={ Challenge }=- 3-Point Circle Tangent to Two Circles, with given Point.

Best way to plot Hyperbolic Cosine curve

Turtle fractals in AutoCAD using .NET - Part 2

The problem I have is I don't fully understand what each of the best-looking AutoLISP solutions are actually doing and/or how to convert them to work with C# .NET.

I also wanted to make use of Kean's Turtle Fractal code, but am unsure of how best to modify it.

Does anyone have any pointers/samples/examples they would mind sharing to get me started (above/beyond those I've posted above)?

(I have almost completed the conversion of the code provided by Swift here: "Best way to plot Hyperbolic Cosine curve" to C# .NET but all that's going to get me is one curve!)

Thanks,

Alex.

PS. all this goes hand-in-hand with a forum post over at reprap.org and a subsequent blog post by Gary Hodgson here.

EDIT 1: Missing url at the end.

#### Gasty

• Newt
• Posts: 48
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #1 on: January 13, 2012, 10:55:42 am »
Hi,

Do you have an algorithm to do that tessellation?, if so, post it (in pseudo code)  along with parameter list, border conditions and every thing else needed, and may be some one here can help you with the code.

Gaston Nunez

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #2 on: January 13, 2012, 11:14:05 am »
Hi Gasty,

At the moment, I don't have anything that can even approach the level of complexity required.

I'm still getting my head around the best way of achieving what I want.

In the meantime, I have managed to complete my translation of the Hyperbolic Cosine Curve Method I linked to above:

Code: [Select]
`        /// <summary>        /// From here: http://bit.ly/yazZHH        /// </summary>        [CommandMethod("HCC")]        static public void hyperbolicCosineCurve()        {            Document doc = Application.DocumentManager.MdiActiveDocument;            Database db = doc.Database;            Editor ed = doc.Editor;            Polyline2d pl;            Point3dCollection pts = new Point3dCollection();            double lowbound;            double upbound;            double step;            double e;            double pi;            double i;            int k;            double[] coords = null;            int start;            int finish;            start =0;            e= Math.E;            pi= Math.PI;            lowbound = 0;            upbound = pi * 2;            step = 0.01;            finish = Convert.ToInt32((upbound - lowbound) / step);            coords = new double[finish * 2 +1];            i = 0;             k = 0;            PromptPointOptions insPoint = new PromptPointOptions("\nPlace the Curve");            insPoint.AllowNone = false;            PromptPointResult res = ed.GetPoint(insPoint);            if (res.Status != PromptStatus.OK)            {                return;            }            Point3d curveStart = res.Value;            for (i = lowbound; i < upbound - step; i+= step) {                coords[k] = i;                k = k + 1;                coords[k] = 0.5 * (Math.Pow(Math.E, i) + Math.Pow(Math.E, -i));                //'coords(k) = Sin(i)                k = k + 1; }            //pts.Add(curveStart); //no need to add our pick point as a point, since the curve starts at a location near to this anyway.            for (i = 0; i < k; i+= 2)            {                int j = Convert.ToInt32(i);                pts.Add(new Point3d(coords[j] + curveStart.X, coords[j + 1] + curveStart.Y, 0));             }            using (Transaction tr = db.TransactionManager.StartTransaction())            {                Polyline3d rectang = new Polyline3d(Poly3dType.SimplePoly,pts, true);                BlockTableRecord btr = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;                btr.AppendEntity(rectang);                tr.AddNewlyCreatedDBObject(rectang, true);                tr.Commit();            }        }`
This creates a Hyperbolic Cosine Curve and adds it to modelspace. I guess I could bolt this method onto the Fractal Tree code that Kean wrote here. (but modify the HCC method to use start and end points generated by the TurtleEngine)

I'll have a think about the points you raised over the weekend and update again on Monday.

Thanks.

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #3 on: January 13, 2012, 11:56:08 am »
FYI: this is the kind of effect I'm looking to create:

#### Gasty

• Newt
• Posts: 48
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #4 on: January 13, 2012, 03:15:24 pm »
Hi Alex:

I found this paper:http://www.d.umn.edu/~ddunham/dundimacs.pdf , it depict an algorithm to tessellate spaces.

Gaston Nunez

#### Kean

• Newt
• Posts: 21
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #5 on: January 16, 2012, 05:03:26 am »
Hi Alex,

Over the weekend I managed to get the code from this post working inside AutoCAD:

http://liris.cnrs.fr/david.coeurjolly/doku/code/poincare

The problem I'm facing is that this creates hyperbolic triangles, but nothing more complex. I've contacted the author, to see what advice he has for me. We'll see if it goes anywhere.

(You can expect a blog post on this at the end of the week, whether I end up being successful getting hyperbolic tilings inside AutoCAD, or not.)

Kean

#### nullptr

• Needs a day job
• Posts: 6554
• AKA Daniel
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #6 on: January 16, 2012, 06:33:53 am »
Ahah! we found something Kean cannot resist

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #7 on: January 16, 2012, 10:54:35 am »
Hi Alex:

I found this paper:http://www.d.umn.edu/~ddunham/dundimacs.pdf , it depict an algorithm to tessellate spaces.

Gaston Nunez
Thanks for the link Gasty, I just realised why I recognized that .pdf by Douglas Dunham; I downloaded a less-technical version of that very document last week.

#### Kean

• Newt
• Posts: 21
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #8 on: January 16, 2012, 11:03:12 am »
Just to keep you all informed... I seem to be making some progress (ahem).

Kean

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #9 on: January 16, 2012, 11:08:14 am »
Just to keep you all informed... I seem to be making some progress (ahem).

Kean
Hehe, looks like it's heading in the right direction Kean. I hope this isn't keeping you too busy..?

#### Kean

• Newt
• Posts: 21
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #10 on: January 16, 2012, 11:09:29 am »
It's too much fun!

Actually things are looking better than I thought, when I reduce the number of "layers"...

Kean

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #11 on: January 16, 2012, 11:59:33 am »
That does look much better.

Is the attached file I found any help?

#### Kean

• Newt
• Posts: 21
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #12 on: January 16, 2012, 03:15:22 pm »
I found the problem - this is looking much better, now.

I'll start posting code later in the week...

Kean

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #13 on: January 16, 2012, 05:02:12 pm »
Hi Kean, that's excellent work.

#### Kean

• Newt
• Posts: 21
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #14 on: January 17, 2012, 10:54:14 am »
Thanks!

Just one last teaser image before I get on and start getting everything together for posting...

Kean

(It'll go out over a couple of posts - Friday and Monday, I expect - so I'll send you something by email, in the meantime, Alex.)

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #15 on: January 17, 2012, 11:52:46 am »
That's really cool! Thanks Kean.

The ability to select the {x,x} iterations would give the users the option of deciding how dense they want the resultant fill to be - is that a function you've built-in?

#### Kean

• Newt
• Posts: 21
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #16 on: January 17, 2012, 11:54:31 am »
Absolutely

#### Kean

• Newt
• Posts: 21
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #17 on: January 20, 2012, 04:56:34 am »

#### qjchen

• Bull Frog
• Posts: 265
• Best wishes to all
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #18 on: January 25, 2012, 08:37:44 am »
Thank you Alex for this funny question.
and thanks Kean for your good .Net function.  I often read you blog and learn a lot from you, thank you Kean

Yesterday I read this topic and found it is a very funny question.
But when I dive into this question, it shocks me, it involves a lot of math problem.
Mobius inversion, Poincare disk, Hyperbolic geometry, symmetric group, .....
I have to read a lot of article to understand it.

Fortunately, I get know of it.
The following code is base on the compass and straightedge constructions (include inversion)
Now it is version 0.1. Can draw a lot of pattern. But duplicated polygon generated, I will improved it in the next version. Now you can use Express tool --overkill to remove this duplicated arcs.

One of my similar work- fractal tree
http://www.theswamp.org/index.php?topic=11255.msg142711#msg142711

Code - Auto/Visual Lisp: [Select]
`;;; ======================================================================== ;;; Some of the following code are writen by CHEN QING JUN                 ; ;;; Civil engineering Department, South China University of Technology     ; ;;; Purpose: To draw Hyperbolic Tessellation, just for fun                 ; ;;; The command name :test                                                 ; ;;; The platform: Acad2000 and after                                       ; ;;; Version: 1.0                                                           ; ;;; Limitation: Many duplication of arc, need to be overkill               ; ;;;             Will be improved in the following version                  ; ;;; Method: From the ideal of http://moniker.name/worldmaking/?p=385       ; ;;; 2012.01.25                                                             ; ;;; ========================================================================  (defun c:test( / layer mspace p q) (setq mSpace (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object)))) (prompt "\n Please note that the following (p-2)*(q-2) should be larger than 4 !") (setq p (getint "\n The polygon size p=?:") q (getint "\n How many Polygon meet at one Vertex. q=?:") layer (getint "\n How many layer,it is better lower than 5, layer=?:")) (if (or (null p) (null q) (null layer)) (setq p 5  q 4  layer 4 )) (if (< (* (- p 2) (- q 2)) 4) (prompt "\n Sorry, you should change p and q")    (progn (q:entmake:circle (list 0 0 0) 1.0 "0" 1)    (makerepeat (DrawCenterPattern p q) layer)) ) (vla-ZoomExtents (vlax-get-acad-object)) (vla-Regen (vla-get-activedocument (vlax-get-acad-object)) :vlax-true) (princ)) ;;;Draw the Center Pattern(defun DrawCenterPattern(p q / c centerplst costheta d k p0 p0new p1new r resx s sintheta sx) ;;This function comes from  http://moniker.name/worldmaking/?p=385 (setq s (sin (/ pi p)) sx (cos (/ pi p)) c (cos (/ pi q)))  (setq r (/ 1 (sqrt (- (/ (* c c) (* s s)) 1)))) (setq d (/ 1 (sqrt (- 1 (/ (* s s) (* c c)))))) (setq k (/ s sx)) ;;resx is the intersection of a line through origin and intersection with the inversion circle (setq resx (q:alg:equation:2 (1+ (* k k)) (* -2 d) (- (* d d) (* r r)))) (setq p0 (list resx (* k resx) 0.)) (setq CenterPlst (cons p0 nil)) (setq sintheta (sin (/ (* 2 pi) p)) costheta (cos (/ (* 2 pi) p))) (repeat (fix (1- p))  (setq p0new (car CenterPlst));;each new point  (setq p1new (list (- (* costheta (car p0new))(* sintheta (cadr p0new)))                    (+ (* sintheta (car p0new))(* costheta (cadr p0new)))              0.0)  );;Rotate p0new by angle (2pi/p)  (q:geo:drawPoinCareArc p0new p1new)  (setq CenterPlst (cons p1new CenterPlst)) ) (q:geo:drawPoinCareArc p1new p0);;Draw the Last hyperbolic line CenterPlst)  ;;;Recursive pattern draw, num is the layer definition(defun makerepeat(lst num / lst1) (setq lst1 (q:list:dealRecur lst)) (if (> num 0)   (progn     (foreach x lst1       (setq res1 (q:geo:inversePlstto2P (cadr x) (car (car x)) (cadr (car x))))       (makerepeat res1 (1- num))     )   ) )) ;; 2d Mirror Function a b defined the mirror line, c is the point to be mirrored(defun q:geo:mirrorp (a b c)  (polar a (- (angle a b) (- (angle a c) (angle a b))) (distance a c))) ;;;;Inverst a Point List about a Hyperbolic line pa-pb Version 0.1;;; Need to be Improved, An Important function of this code(defun q:geo:inversePlstto2P(plst pa pb / pav pcenter pnew res x)  (setq pav (q:geo:invert0 pa))  (setq res (list pb pa))  (if (< (q:vec:Length (q:vec:cross* pa pb)) 1e-7)    (progn     (foreach x plst	 (setq pnew (q:geo:mirrorp pa pb x)	       res (cons pnew res))	 (q:geo:drawPoinCareArc (car res) (cadr res))     )   );;;This code deal with the line (pa,pb) pass origin   (progn     (setq pcenter (q:geo:circumcircle3d pa pb pav))     (foreach x plst	 (setq pnew (q:geo:invert1 x (car pcenter) (cadr pcenter))	       res (cons pnew res))	 (q:geo:drawPoinCareArc (car res) (cadr res))     )     (q:geo:drawPoinCareArc (car res) (last res));;Draw the last arc   )  )  (reverse res))  ;;;A special List deal, Convert '(1 2 3 4 5 ) to ;;;(((1 2)(3 4 5)),((2 3)(4 5 1),((3 4)(5 1 2)),((4 5)(1 2 3)),((5 1)(2 3 4)));;;A rotation of the List, each contain (3 4) two element, and the other by order.(defun q:list:dealRecur(lst / i len lst3 res) (if (<= (setq len (length lst)) 2) (setq res nil)   (progn    (setq lst (append lst lst) i 0)    (repeat len     (setq lst3 (list (list (nth i lst) (nth (1+ i) lst)) (q:list:N+num lst (+ i 2) (- len 2)))	   res (cons lst3 res)	   i (1+ i))    )    ) ) (reverse res));;;;Draw Hyperbolic line in Poincare disk, Two Condition is consider(defun q:geo:drawPoinCareArc(pa pb / ang1 ang2 arcobj pav pcenter temp) (setq pav (q:geo:invert0 pa))  (if (< (q:vec:Length (q:vec:cross* pa pb)) 1e-7)  ;;;Which means the line (pa,pb) go through origin    (vla-AddLine mSpace (vlax-3d-point pa)(vlax-3d-point pb))    (progn     (setq pcenter (q:geo:circumcircle3d pa pb pav)           ang1 (angle (car pcenter) pa)            ang2 (angle (car pcenter) pb))     (if (> ang1 ang2) (setq temp ang1 ang1 ang2 ang2 temp))     (if (> ang2 (+ pi ang1)) (setq temp ang1 ang1 ang2 ang2 temp))     (setq arcObj (vla-AddArc mSpace (vlax-3d-point (car pcenter)) (cadr pcenter) ang1 ang2))    ) ));;;Inverse a point to a unit circle(defun q:geo:invert0(p / d) (setq d (distance p (list 0 0 0))) (if (< d 1e-7) nil (q:vec:*c p (/ 1 d d))));;;Inverse a point to a circle with center and radius r.(defun q:geo:invert1(p center r / d p1 p2) (setq d (distance p center)) (if (< d 1e-7) nil   (progn (setq p1 (q:vec:- p center) p2 (q:vec:*c p1 (/ (* r r) d d )))    (q:vec:+ p2 center)   ) ));;;__________________________________________________________________;;;;;General Function                                                  ;;;;;__________________________________________________________________;;;;;Get SubList of Lst from N to N+num(defun q:list:N+num(lst N num / c res) (repeat N (setq lst (cdr lst))) (repeat num (if (setq c (car lst)) (setq res (cons c res) lst (cdr lst)))) (reverse res));;;Solve Quadratic Equations and Get Only the small one. Return nil if no solution(defun q:alg:equation:2(a b c)  (if (< (setq temp (- (* b b) (* a c 4.))) 0) nil  (/ (- 0 b (sqrt temp)) 2. a)));;entmake Circle(defun q:entmake:circle (center rad layer color)  (entmake (list (cons 0 "CIRCLE")(cons 6 "BYLAYER")   (cons 8 layer) (cons 10 center)(cons 40 rad)(cons 62 color))));;;;vec plus(defun q:vec:+(v1 v2) (mapcar '+ v1 v2));;;;vec substract(defun q:vec:-(v1 v2) (mapcar '- v1 v2));;;;vec plus constant(defun q:vec:*c(v a)  (mapcar '(lambda(x) (* x a)) v));;;;vec dot product(defun q:vec:dot*(v1 v2) (apply '+ (mapcar '* v1 v2)));;;;vec cross product(defun q:vec:cross*(v1 v2)  (list (q:det:2 (cadr v1) (caddr v1) (cadr v2) (caddr v2))        (q:det:2 (caddr v1) (car v1) (caddr v2) (car v2))        (q:det:2 (car v1) (cadr v1) (car v2) (cadr v2))) );;;;Normalize a vec(defun q:vec:Norm(v / l)  (if (not (zerop (setq l (distance '(0 0 0) v))))  (mapcar '(lambda(x) (/ x l)) v)));;;; Vector Length(defun q:vec:Length(v) (sqrt (apply '+ (mapcar '(lambda(x) (expt x 2)) v))));;;;determinant library;;;;cal determinant ;;;;|a1 a2|;;;;|b1 b2|(defun q:det:2(a1 a2 b1 b2)  (- (* a1 b2) (* a2 b1)));;;;;;;;;;;;;;;;;;;;;;;;;;;;Use Barycentric Coordinates to calculate multiple center;;;http://mathworld.wolfram.com/BarycentricCoordinates.html;;;http://en.wikipedia.org/wiki/Barycentric_coordinates_(mathematics)#Converting_to_barycentric_coordinates(defun q:geo:barycentric-normalize(a b c)  (mapcar '(lambda(x) (/ x (+ a b c))) (list a b c)));;;;transform from barycentric-to-Cartesian coordinate(defun q:geo:barycentric-to-Cartesian(tlst P1 P2 P3) (q:vec:+  (q:vec:+ (q:vec:*c P1 (car tlst)) (q:vec:*c P2 (cadr tlst))) (q:vec:*c P3 (caddr tlst))));;Find out the circumcircle of three point (three distinct, noncollinear WCS points);;;; qjchen@gmail.com(defun q:geo:circumcircle3d(p1 p2 p3 / a b c p temp)  (setq a (distance p2 p3) b (distance p1 p3) c (distance p1 p2))  (defun temp(a b c) (* a a (+ (* b b) (* c c) (* a (- a)))))  (setq p  (q:geo:barycentric-to-Cartesian (q:geo:barycentric-normalize (temp a b c) (temp b c a) (temp c a b)) P1 P2 P3))  (list p (distance p1 p)))  (princ "\n By qjchen@gmail.com, Hyperbolic Tessellation. 1.0, The command is TEST")(princ) `

Some useful article for this problem
http://liris.cnrs.fr/david.coeurjolly/doku/code/poincare
https://svn.liris.cnrs.fr/dcoeurjo/Poincare/cairoPoincare.h
http://www.jasondavies.com/poincare-disc/
http://www.bugman123.com/Hyperbolic/index.html
http://zueuk.deviantart.com/gallery/
http://www.povray.org/
http://jsxgraph.uni-bayreuth.de/wiki/index.php/Poincare_disc_model
http://apps.hi.baidu.com/share/detail/34282038
http://zh.wikipedia.org/wiki/%E8%8E%AB%E6%AF%94%E4%B9%8C%E6%96%AF%E5%8F%98%E6%8D%A2
http://en.wikipedia.org/wiki/Poincar%C3%A9_disc_model
http://jsxgraph.uni-bayreuth.de/wiki/index.php/Category:Examples
http://moniker.name/worldmaking/?p=385
http://www.d.umn.edu/~ddunham/
http://hyperart.cvs.sourceforge.net/viewvc/hyperart/hyperart/
http://www.rockini.name/gallery00.php

« Last Edit: January 25, 2012, 08:45:52 am by qjchen »
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #19 on: January 25, 2012, 08:58:20 am »
That's a pretty comprehensive list of links, thanks!

I'm in the process of converting Kean's .NET classes to use in Inventor. Wish me luck!

#### qjchen

• Bull Frog
• Posts: 265
• Best wishes to all
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #20 on: January 25, 2012, 09:03:13 am »
That's a pretty comprehensive list of links, thanks!

I'm in the process of converting Kean's .NET classes to use in Inventor. Wish me luck!

Best wishes , I am sure you could convert Kean's code to Inventor, then you could do wonderful 3d artworks~
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #21 on: January 25, 2012, 09:15:14 am »
the ultimate goal is to create this kind of pattern in 3D and use it as a sub-structure within parts that are destined to be 3D Printed.

So far, I've been able to create the following part in Inventor: (See attached)

EDIT for clarity: This part was created by importing the hyperbolic geometry created in AutoCAD into Inventor's sketch environment.

#### ElpanovEvgeniy

• Swamp Rat
• Posts: 1398
• Moscow (Russia)
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #22 on: January 26, 2012, 01:19:40 am »
Thank you! Very interesting topic...
I think the proposed way to reduce the amount of material for 3D printing is too complicated! I suggest using the triangle (tetrahedron) or squares (cubes).
В жизни нет хорошего или плохого, а есть лишь бесконечные возможности для обучения.

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #23 on: January 26, 2012, 03:32:19 am »
Evgeniy, you are correct that this is complicated, but I don't think it's overly complex - at least not when compared to how nature does it. (think bird skulls/bones etc.)

The use of hyperbolic tessellation (regardless of what {x,x} iterations you use) is one way to provide a good blend of material saving and strength. (At least until I or someone else can test it and prove otherwise)

#### qjchen

• Bull Frog
• Posts: 265
• Best wishes to all
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #24 on: January 26, 2012, 09:15:12 am »
Thank you, Alex, for your beautiful Inventor pattern picture.~
And thanks Evgeniy for this beautiful Euclidean Recursive Picture.
http://qjchen.mjtd.com
My blog http://chenqj.blogspot.com (Chinese, can be translate into English)

#### AlexF

• Bull Frog
• Posts: 247
##### Re: Hyperbolic Tessellation using C# .NET
« Reply #25 on: February 07, 2012, 08:23:32 am »
I now have a (more-or-less) working native-Inventor implementation of the code provided by Kean.

There are still a few issues surrounding the number of lines produced when creating each polygon - namely that each line (up to but not including the outer "layer") is part of 2 polygons, therefore you end up with twice as many lines as are required.

And I also need to look again at the setup dialogues - currently (And I can only assume because something got lost in the translation from C# to VB.NET) I can only pick 7-sided polygons with 3 meeting at each intersection and > 2 layers.

Ideally I think I'd want to emulate as closely as possible the fine degree of control afforded by Kean's solution.

Anyway, here's my code:

(See attached.)