Software that makes placemats

Organise events to meet up and drink Port.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

Edited Wed 19th June to rename Dists ➝ Pot. Please, no jokes.

Possible algorithm for assigning charges

Circles either have a charge assigned (hurray!), which is one of {1,2,3}. Or don’t yet, in which case deemed charge is 0.

Repeatedly we’ll compute, for circle i, Poti0, Poti1, Poti2, and Poti3.

Potik ≡ ∑j ( (xixj)² + (yiyj)² )⁻¹ where ji and circle j has charge k.

Pick of the i with no assigned charge the largest value of Poti0÷1024 + Poti1 + Poti2 + Poti3

Assign to it the the charge {3,1,2} according to whichever is smallest of Poti3, Poti1, Poti2, with ties being resolved in that order.

Repeat until all charges assigned.

Observe: easy to code; O(n³) which is acceptable with n≤24; effectively maximises distance between similar charges; starts in centre and chooses circles adjacent to those with known charge, working outwards.

Good? Bad? Improvements?

(But I still have no idea how to compute the streams. Help!)
akzy
Warre’s Otima 10 year old Tawny
Posts: 537
Joined: 21:42 Tue 13 Nov 2018
Location: Three Bridges

Re: Software that makes placemats

Post by akzy »

jdaw1 wrote: 20:39 Tue 18 Jun 2019 Charges good. Because circles touch, hexagonal was better.
I never said it was an efficient packing :) - either way, looks like its producing decent results. As for the charges it may start to look a bit funky on large arrays due to edge effects and failing large scale symmetry. I think the solution is "have a play around".

As for you algorithm, it seems good. I think seeing it in action will let us know how well it looks.

For manually making a StreamPlot (I think this is what you meant?) I imagine that will be tougher. What I suggest is that we...

1. Create field seed spots at the edges of the circles (at whatever density we decide).
2. At that point, we have a vector (from potgridx and potgridy) telling us where the field goes next.
3. Follow that on some small distance (there is definitely a mathematical way of determining how small this distance is - I cant' remember however).
4. Return back to step 2 until you're off the mat or in another circle.
5. Fit a curve to each trace.

I'm a touch busy atm with pesky thesis writing (we'll forget about a week in Provence coming soon) but if I get some time, I can try have a play with it.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

akzy wrote: 18:05 Wed 19 Jun 2019For manually making a StreamPlot (I think this is what you meant?) I imagine that will be tougher.
I am absolutely sure it will be very tricky.
akzy wrote: 18:05 Wed 19 Jun 2019Create field seed spots at the edges of the circles (at whatever density we decide).
Or choose seed points in a small circle around a charge, perhaps every 15°. Flow uphill. But those won’t arrive at even angles at other charges, nor at even distances at edge. Then what? I don’t know.

Also, can the flow uphill be ‘locally’ analytic? If it could be known quite well over a moderate distance, that could be converted to a single Bézier cubic using ApproximatingCurve.
User avatar
Alex Bridgeman
Graham’s 1948
Posts: 14880
Joined: 13:41 Mon 25 Jun 2007
Location: Berkshire, UK

Re: Software that makes placemats

Post by Alex Bridgeman »

jdaw1 wrote: 22:45 Mon 17 Jun 2019 Others: please take sides.
Sorry? Did someone say something?

Wake me up when it's over and someone can explain in English what just happened...
Top Ports in 2023: Taylor 1896 Colheita, b. 2021. A perfect Port.

2024: Niepoort 1900 Colheita, b.1971. A near perfect Port.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

jdaw1 wrote: 23:17 Tue 18 Jun 2019Possible algorithm for assigning charges

Circles either have a charge assigned (hurray!), which is one of {1,2,3}. Or don’t yet, in which case deemed charge is 0.

Repeatedly we’ll compute, for circle i, Poti0, Poti1, Poti2, and Poti3.

Potik ≡ ∑j ( (xixj)² + (yiyj)² )⁻¹ where ji and circle j has charge k.

Pick of the i with no assigned charge the largest value of Poti0÷1024 + Poti1 + Poti2 + Poti3

Assign to it the the charge {3,1,2} according to whichever is smallest of Poti3, Poti1, Poti2, with ties being resolved in that order.

Repeat until all charges assigned.
Test implementation of the charge assignment: output looks good — nearby circles have different charges; PostScript code follows.

Code: Select all

/ParametersVersionDateTimeAdobeFormat (D:201906202330) def

/Circlearrays [ [/lozenge] 15 {dup} repeat pop ] def
/Titles [ ( ) 15 {dup} repeat pop ] def

/Belowtitles [ Titles length {()} repeat ] def

/Names [
	(JDAW)
] def

/HeadersLeft [
	0  [(Assigning charges: a test)]
] def  % /HeadersLeft
/HeadersCenter [
] def  % /HeadersCenter
/HeadersRight [
	0
	{ExternalLinks 2 get}
] def  % /HeadersRight
/ExternalLinks [  % Array, length a multiple of three:  indented0-boolean, (Descriptor0), (http://URL0),  indented1-boolean, (Descriptor1), (http://URL1),  ...
	false   (Thread on ThePortForum.com)     (http://www.theportforum.com/viewtopic.php?t=175&start=1136#p112232)
	false   (Algorithm on ThePortForum.com)  (http://www.theportforum.com/viewtopic.php?p=112250#p112250)
	false   (Latest version this placemat)   (http://www.jdawiseman.com/papers/2019/20190620_Charges.pdf)
] def  % /ExternalLinks

/VoteRecorders false def
/CorkDisplayNumCopies 0 def
/NeckTagsNumCopies 0 def
/DecantingNotesNumCopies 0 def
/TastingNotePagesNumCopies 0 def

/PaperType { [ /A3 /A4 dup dup dup /A3 dup dup dup] SheetNum get }  def
/Orientation {SheetNum 1 eq SheetNum 2 eq or {/Portrait} {/Landscape} ifelse} def  % /Landscape /Portrait

/GlassesOnSheets [
	[ 7 5 6 5 7 11 13 14 15 ]
		{ [ exch 0 exch 1 exch 1 sub {} for ] }
	forall
] def  % /GlassesOnSheets

/ShrinkRadii /NotAtAll def  % /NotAtAll | /ToSmallest | /ToSmallestSamePageOrdering | array denoting equivalence classes

/PackingStyles [
	[ /RectangularDislocation /OnlyIfSheetNumMin 1 ]
	[ /Diamonds /OnlyIfSheetNumMin 1 ]
	[ /DiamondsAndRectangular /OnlyIfSheetNumMin 1 ]
	[ /Bespoke5  /OnlyIfOrientation /Landscape /OnlyIfSheetNumMin 1 ]
	[ /Bespoke7  /OnlyIfOrientation /Landscape/OnlyIfSheetNumMin 1 ]
	[ /RectangularAlternateSplitNudge /OnlyIfSheetNumMin 1  /ImprovementPointsMin 2 ]
	[ /DiamondsPlus  /OnlyIfOrientation /Portrait /OnlyIfSheetNumMin 1 ]
	[ /DiamondsPlus  /OnlyIfOrientation /Landscape /OnlyIfSheetNumMin 1  /ImprovementPointsMin 2 ]
	[ /RectangularAlternateNudge /OnlyIfSheetNumMin 1  /ImprovementPointsMin 2 ]
	[ /Arch            /CentralGlasses 1  /GlassesNumMin 6  /OnlyIfOrientation /Landscape  ]
] def  % /PackingStyles

/PaintBackgroundCode
{
	% Done properly, the computations would be in PrologueCode, and only the painting in PaintBackgroundCode.
	/Glasses TypeOfPagesBeingRendered eq
	{
		10 dict begin
		/N1s  GlassPositions SheetNum get length 1 sub  def
		/Xs [ GlassPositions SheetNum get {0 get} forall ] def
		/Ys [ GlassPositions SheetNum get {1 get} forall ] def
		/Charges [ 0   N1s {dup} repeat ]  def
		/Title 1 string def  Title 0 65 put

		N1s 1 add
		{
			/Pot [ 4 { [ 0  N1s {dup} repeat ] } repeat ] def
			0  1  N1s
			{
				/i exch def
				0  1  N1s
				{
					/j exch def
					i  j  ne
					{
						Pot Charges j get get  i   2 copy get   1  Xs i get Xs j get sub dup mul Ys i get Ys j get sub dup mul add  div  add   put
					} if  % i  j  ne
				} for  % j
			} for  % i

			/PotMax -1 def
			/iBest -1 def
			0  1  N1s
			{
				/i exch def
				Charges i get  0  eq
				{
					Pot 0 get i get 1024 div  Pot 1 get i get add  Pot 2 get i get add  Pot 3 get i get add
					dup PotMax gt {/PotMax exch def  /iBest i def} {pop} ifelse
				} if  % Charges i get  0  eq
			} for  % i

			Charges  iBest
			Pot 3 get iBest get  Pot 1 get iBest get  le
				{Pot 3 get iBest get  Pot 2 get iBest get  le {3} {2} ifelse}
				{Pot 1 get iBest get  Pot 2 get iBest get  le {1} {2} ifelse}
			ifelse  put

			TitlesFont RadiiCirclearrayInside SheetNum get 1.9 mul selectfont
			GlassPositions SheetNum get iBest get aload pop moveto
			GSave nulldevice 0 0 moveto Title false CharPathRecursive PathBBox GRestore  exch 4 -1 roll add -2 div 3 1 roll add -2 div rmoveto
			[ {/Error} {0.8 setgray} {0.4 0.4 0.5 setrgbcolor} {0.6 0 0 setrgbcolor} ] Charges iBest get get exec
			Title ShowRecursive
			Title 0 2 copy get 1 add put
		} repeat
		end
	} if
} bind def
But the charge assignment is the easy bit. Making the streams will be much much more tricky.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

More realistic example at jdawiseman.com/2019/20190623_Rays_A4.nb.

Code: Select all

h = 297 (360/127) - 30 - 24;
w = 210 (360/127) - 24 - 24;
r = w/4;
Clear["yy"]; yy = yy /. Solve[(yy - r)^2 == (h - r - yy)^2 + (w/2 - r)^2, yy][[1]];
Print["h=", h, "   w=", w, "   r=", r, "   yy=", yy];

Print[N[circlevec = {
      	{w/2, h - r, 2},
      	{r, yy, 3},
      	{w - r, yy, 1},
      	{r, r, 2},
      	{w - r, r, 3}
      }] // MatrixForm];
p1 = Map[Graphics[{Red, Thick, Circle[{#[[1]], #[[2]]}, r]}] &, circlevec[[All, 1 ;; 2]]];
p2 = Graphics[Map[Text[Style[#[[3]], FontSize -> 60, Bold, Green], {#[[1]], #[[2]]}, {0, 0}] &, circlevec]];
pot[x_, y_, qx_, qy_, q_] := q/Sqrt[(x - qx)^2 + (y - qy)^2];
potgridx[x_, y_] = D[Total[Table[pot[x, y, circlevec[[i, 1]], circlevec[[i, 2]], circlevec[[i, 3]]], {i, 1, Length[circlevec]}]], x];
potgridy[x_, y_] = D[Total[Table[pot[x, y, circlevec[[i, 1]], circlevec[[i, 2]], circlevec[[i, 3]]], {i, 1, Length[circlevec]}]], y];
p3 = StreamPlot[{potgridx[x, y], potgridy[x, y]}, {x, 0, w}, {y, 0, h}];
Show[p1, p2, p3, AspectRatio -> h/w]
In the picture green numbers are the charges.

Image

If only StreamPlot weren’t so fiercely difficult to re-code.
PhilW
Dalva Golden White Colheita 1952
Posts: 3503
Joined: 14:22 Wed 15 Dec 2010
Location: Near Cambridge, UK

Re: Software that makes placemats

Post by PhilW »

A suggestion for alternate charge-plan to try and regularise:
- For every circle, inscribe a hexagon (possibly slightly smaller diameter).
- Assign charge to hexagon points (instead of circle centres), all with +1 at top point, then alternating -1/+1 around the hexagon.
In any square or hexagonal arrangement of circles, that should avoid like charges bring close, allowing good connectivity between, while also being regular/simple charge definition for all layouts.
PhilW
Dalva Golden White Colheita 1952
Posts: 3503
Joined: 14:22 Wed 15 Dec 2010
Location: Near Cambridge, UK

Re: Software that makes placemats

Post by PhilW »

If only StreamPlot weren’t so fiercely difficult to re-code.
Do you have a pseudo-code algorithm?
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

PhilW wrote: 21:23 Sun 23 Jun 2019A suggestion for alternate charge-plan to try and regularise:
- For every circle, inscribe a hexagon (possibly slightly smaller diameter).
- Assign charge to hexagon points (instead of circle centres), all with +1 at top point, then alternating -1/+1 around the hexagon.
In any square or hexagonal arrangement of circles, that should avoid like charges bring close, allowing good connectivity between, while also being regular/simple charge definition for all layouts.
Interesting. I will test. Might the mesh of points be too fine — points too close — such that it loses the macro structure?

PhilW wrote: 21:24 Sun 23 Jun 2019
If only StreamPlot weren’t so fiercely difficult to re-code.
Do you have a pseudo-code algorithm?
No.
PhilW
Dalva Golden White Colheita 1952
Posts: 3503
Joined: 14:22 Wed 15 Dec 2010
Location: Near Cambridge, UK

Re: RE: Re: Software that makes placemats

Post by PhilW »


jdaw1 wrote:Interesting. I will test. Might the mesh of points be too fine — points too close — such that it loses the macro structure?
My gut feel was that it should be viable for hexagons, but that moving to decagons or higher 2*oddN sided polygons would be too fine. Might/not work, but thought worth suggesting to try.

User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

.nb

Code: Select all

h = 297 (360/127) - 30 - 24;
w = 210 (360/127) - 24 - 24;
r = w/4;
Clear["yy"]; yy = 
 yy /. Solve[(yy - r)^2 == (h - r - yy)^2 + (w/2 - r)^2, yy][[1]];
Print["h=", h, "   w=", w, "   r=", r, "   yy=", yy];

Print[N[circleCentres = {
      	{w/2, h - r},
      	{r, yy},
      	{w - r, yy},
      	{r, r},
      	{w - r, r}
      }] // MatrixForm];
p1 = Map[Graphics[{Red, Thick, Circle[{#[[1]], #[[2]]}, r]}] &, 
   circleCentres];
charges = Flatten[Map[{
      	{#[[1]], #[[2]] + r, +1},
      	{#[[1]] + r Sqrt[3]/2, #[[2]] + r/2, -1},
      	{#[[1]] + r Sqrt[3]/2, #[[2]] - r/2, +1},
      	{#[[1]], #[[2]] - r, -1},
      	{#[[1]] - r Sqrt[3]/2, #[[2]] - r/2, +1},
      	{#[[1]] - r Sqrt[3]/2, #[[2]] + r/2, -1}
      } &, circleCentres], 1];
p2 = Map[Graphics[{Green, Thick, Circle[{#[[1]], #[[2]]}, r/48]}] &, 
   charges];
pot[x_, y_, qx_, qy_, q_] := q/Sqrt[(x - qx)^2 + (y - qy)^2];
potgridx[x_, y_] = 
  D[Total[Table[
     pot[x, y, charges[[i, 1]], charges[[i, 2]], charges[[i, 3]]], {i,
       1, Length[charges]}]], x];
potgridy[x_, y_] = 
  D[Total[Table[
     pot[x, y, charges[[i, 1]], charges[[i, 2]], charges[[i, 3]]], {i,
       1, Length[charges]}]], y];
p3 = StreamPlot[{potgridx[x, y], potgridy[x, y]}, {x, 0, w}, {y, 0, 
    h}];
Show[p1, p2, p3, AspectRatio -> h/w]
Image
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

.nb

Code: Select all

h = 297 (360/127) - 30 - 24;
w = 210 (360/127) - 24 - 24;
r = w/4;
Clear["yy"]; yy = 
 yy /. Solve[(yy - r)^2 == (h - r - yy)^2 + (w/2 - r)^2, yy][[1]];
Print["h=", h, "   w=", w, "   r=", r, "   yy=", yy];

Print[N[circleCentres = {
      	{w/2, h - r},
      	{r, yy},
      	{w - r, yy},
      	{r, r},
      	{w - r, r}
      }] // MatrixForm];
p1 = Map[Graphics[{Red, Thick, Circle[{#[[1]], #[[2]]}, r]}] &, 
   circleCentres];
charges = Flatten[Map[{
      	{#[[1]], #[[2]] + r, +1},
      	{#[[1]] + r, #[[2]], -1},
      	{#[[1]], #[[2]] - r, +1},
      	{#[[1]] - r, #[[2]], -1}
      } &, circleCentres], 1];
p2 = Map[Graphics[{Green, Thick, Circle[{#[[1]], #[[2]]}, r/48]}] &, 
   charges];
pot[x_, y_, qx_, qy_, q_] := q/Sqrt[(x - qx)^2 + (y - qy)^2];
potgridx[x_, y_] = 
  D[Total[Table[
     pot[x, y, charges[[i, 1]], charges[[i, 2]], charges[[i, 3]]], {i,
       1, Length[charges]}]], x];
potgridy[x_, y_] = 
  D[Total[Table[
     pot[x, y, charges[[i, 1]], charges[[i, 2]], charges[[i, 3]]], {i,
       1, Length[charges]}]], y];
p3 = StreamPlot[{potgridx[x, y], potgridy[x, y]}, {x, 0, w}, {y, 0, 
    h}];
Show[p1, p2, p3, AspectRatio -> h/w]
Image
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

All this is conditional in being able to implement StreamPlot. Subject to which, do we want the average charge to be zero, or to have the inward flow from all charges being positive?

Also, is Phil’s plan too symmetrical. Does the rigorous symmetry cause non-interestingness?
akzy
Warre’s Otima 10 year old Tawny
Posts: 537
Joined: 21:42 Tue 13 Nov 2018
Location: Three Bridges

Re: Software that makes placemats

Post by akzy »

Are you able to implement python in postscript? If so matplotlib has the stream plot coded out for you https://github.com/matplotlib/matplotli ... eamplot.py

Another option is manually translate into whatever language.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

akzy wrote: 17:34 Wed 26 Jun 2019Are you able to implement python in postscript? If so matplotlib has the stream plot coded out for you https://github.com/matplotlib/matplotli ... eamplot.py

Another option is manually translate into whatever language.
{Shudder} Translating that to PostScript would likely as not be 3k lines. {Shudder}
PhilW
Dalva Golden White Colheita 1952
Posts: 3503
Joined: 14:22 Wed 15 Dec 2010
Location: Near Cambridge, UK

Re: Software that makes placemats

Post by PhilW »

The first of your two examples does set the charges on hexagonal points as suggested, but puts them on the circle perimeter - I think it would work better if they were at ~85% of the radius.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

PhilW wrote: 07:55 Fri 28 Jun 2019The first of your two examples does set the charges on hexagonal points as suggested, but puts them on the circle perimeter - I think it would work better if they were at ~85% of the radius.
.nb

Code: Select all

h = 297 (360/127) - 30 - 24;
w = 210 (360/127) - 24 - 24;
r = w/4;
rr = 0.85 r;
Clear["yy"]; yy = 
 yy /. Solve[(yy - r)^2 == (h - r - yy)^2 + (w/2 - r)^2, yy][[1]];
Print["h=", h, "   w=", w, "   r=", r, "   yy=", yy];

Print[N[circleCentres = {
      	{w/2, h - r},
      	{r, yy},
      	{w - r, yy},
      	{r, r},
      	{w - r, r}
      }] // MatrixForm];
p1 = Map[Graphics[{Red, Thick, Circle[{#[[1]], #[[2]]}, r]}] &, 
   circleCentres];
charges = Flatten[Map[{
      	{#[[1]]                               , #[[2]] + rr, +1},
      	{#[[1]] + rr Sqrt[3]/2, #[[2]] + rr/2, -1},
      	{#[[1]] + rr Sqrt[3]/2, #[[2]] - rr/2, +1},
      	{#[[1]]                               , #[[2]] - rr, -1},
      	{#[[1]] - rr Sqrt[3]/2, #[[2]] - rr/2, +1},
      	{#[[1]] - rr Sqrt[3]/2, #[[2]] + rr/2, -1}
      } &, circleCentres], 1];
p2 = Map[Graphics[{Green, Thick, Circle[{#[[1]], #[[2]]}, r/48]}] &, charges];
pot[x_, y_, qx_, qy_, q_] := q/Sqrt[(x - qx)^2 + (y - qy)^2];
potgridx[x_, y_] = D[Total[Table[pot[x, y, charges[[i, 1]], charges[[i, 2]], charges[[i, 3]]], {i,1, Length[charges]}]], x];
potgridy[x_, y_] = D[Total[Table[pot[x, y, charges[[i, 1]], charges[[i, 2]],charges[[i, 3]]], {i, 1, Length[charges]}]], y];
p3 = StreamPlot[{potgridx[x, y], potgridy[x, y]}, {x, 0, w}, {y, 0, h}];
Show[p1, p2, p3, AspectRatio -> h/w]
Image


I prefer:
jdaw1 wrote: 17:01 Sun 23 Jun 2019Image
Why? The inward pointing of the lines, the sitting in its own gravitational well, has the outside pointing to the important stuff — the juice. Within which I like the visual interest of not having macro symmetry. And the fewness of the lines hides the micro structure of 6× as many charges.
PhilW
Dalva Golden White Colheita 1952
Posts: 3503
Joined: 14:22 Wed 15 Dec 2010
Location: Near Cambridge, UK

Re: Software that makes placemats

Post by PhilW »

jdaw1 wrote: 23:56 Fri 28 Jun 2019I prefer:
jdaw1 wrote: 17:01 Sun 23 Jun 2019Image
Why? The inward pointing of the lines, the sitting in its own gravitational well, has the outside pointing to the important stuff — the juice. Within which I like the visual interest of not having macro symmetry. And the fewness of the lines hides the micro structure of 6× as many charges.
I agree with the preference, because of the inward/outward pointing of the lines, though I would also prefer macro symmetry; I was hoping to achieve the former with the regular hexagon plan by moving the charges further inside, but alas that doesn't seem sufficient.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

PhilW wrote: 06:46 Sat 29 Jun 2019I agree with the preference, because of the inward/outward pointing of the lines, though I would also prefer macro symmetry; I was hoping to achieve the former with the regular hexagon plan by moving the charges further inside, but alas that doesn't seem sufficient.
First (.nb) has shuffled charges, integers from half the number of glasses to 1½× that.

Code: Select all

h = 297 (360/127) - 30 - 24;
w = 210 (360/127) - 24 - 24;
r = w/4;
Clear["yy"]; yy = yy /. Solve[(yy - r)^2 == (h - r - yy)^2 + (w/2 - r)^2, yy][[1]];
Print["h=", h, "   w=", w, "   r=", r, "   yy=", yy];
Print[N[circleCentres = {
      	{w/2, h - r},
      	{r, yy},
      	{w - r, yy},
      	{r, r},
      	{w - r, r}
      }] // MatrixForm];
charges = Transpose[Join[Transpose[circleCentres], {RandomSample[Floor[Length[circleCentres]/2] + Range[Length[circleCentres]]]}]];
p1 = Map[Graphics[{Red, Thick, Circle[{#[[1]], #[[2]]}, r]}] &, circleCentres];
p2 = Graphics[ Map[Text[Style[#[[3]], FontSize -> 60, Bold, Green], {#[[1]], #[[2]]}, {0, 0}] &, charges]];
pot[x_, y_, qx_, qy_, q_] := q/Sqrt[(x - qx)^2 + (y - qy)^2];
potgridx[x_, y_] = D[Total[Table[pot[x, y, charges[[i, 1]], charges[[i, 2]], charges[[i, 3]]], {i, 1, Length[charges]}]], x];
potgridy[x_, y_] = D[Total[Table[pot[x, y, charges[[i, 1]], charges[[i, 2]], charges[[i, 3]]], {i, 1, Length[charges]}]], y];
p3 = StreamPlot[{potgridx[x, y], potgridy[x, y]}, {x, 0, w}, {y, 0, h}];
Show[p1, p2, p3, AspectRatio -> h/w]
Image

Second (.nb) has all charges the same, for greater macro symmetry.
Image

For my taste the variety of charges add to the visual texture, and also reduces the numerical sensitivity near lines of local symmetry.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

jdaw1 wrote: 23:17 Thu 27 Jun 2019
akzy wrote: 17:34 Wed 26 Jun 2019Are you able to implement python in postscript? If so matplotlib has the stream plot coded out for you https://github.com/matplotlib/matplotli ... eamplot.py

Another option is manually translate into whatever language.
{Shudder} Translating that to PostScript would likely as not be 3k lines. {Shudder}
This builds a StreamPlot from a low-resolution two-dimensional array. Ouch. Looking for an algorithm to which takes a function, the function taking (x, y) and returning the potential and appropriate derivatives.

Note to self: Rainer Wegenkittl and Eduard Gröller.
akzy
Warre’s Otima 10 year old Tawny
Posts: 537
Joined: 21:42 Tue 13 Nov 2018
Location: Three Bridges

Re: Software that makes placemats

Post by akzy »

jdaw1 wrote: 10:13 Sat 29 Jun 2019
jdaw1 wrote: 23:17 Thu 27 Jun 2019
akzy wrote: 17:34 Wed 26 Jun 2019Are you able to implement python in postscript? If so matplotlib has the stream plot coded out for you https://github.com/matplotlib/matplotli ... eamplot.py

Another option is manually translate into whatever language.
{Shudder} Translating that to PostScript would likely as not be 3k lines. {Shudder}
This builds a StreamPlot from a low-resolution two-dimensional array. Ouch. Looking for an algorithm to which takes a function, the function taking (x, y) and returning the potential and appropriate derivatives.

Note to self: Rainer Wegenkittl and Eduard Gröller.
This, I reckon, is going to be significantly harder. I will keep having a look around - there surely is some open source version of it somewhere (haven't had the proper chance to look into the paper you linked yet).
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

This might be easy.
• Don’t have the complicated lines. Instead have separate droplets, starting thin pale grey, ending thicker darker.
• Droplets start on a jittered hexagonal grid. Average distance a parameter, perhaps defaulting to 36pt = ½″ = 12.7mm.
• Droplets advance in small steps downhill (2pt steps?), with no momentum.
• If consecutive steps have angle ≥10°, next step halved. (Or can optimal path length be deduced from second derivatives? Help!)
• Path ends if too close to any charge, or if total distance traversed exceeds some multiple of the average distance apart (perhaps defaulting to 1×).
• That array of path arrays stored, and painted for each page under everything else.

Thoughts?
akzy
Warre’s Otima 10 year old Tawny
Posts: 537
Joined: 21:42 Tue 13 Nov 2018
Location: Three Bridges

Re: Software that makes placemats

Post by akzy »

This seems similar to what I proposed before except we don't do a line fit (as far as I understand) and you start on an arbitrary hexagonal grid. I think the seeds on circle edges might work better, but providing it's easy to play with, have a try both ways.
akzy wrote: 18:05 Wed 19 Jun 2019 1. Create field seed spots at the edges of the circles (at whatever density we decide).
2. At that point, we have a vector (from potgridx and potgridy) telling us where the field goes next.
3. Follow that on some small distance (there is definitely a mathematical way of determining how small this distance is - I cant' remember however).
4. Return back to step 2 until you're off the mat or in another circle.
5. Fit a curve to each trace.
Providing your postscript code is fine with calculating potgrid analytically (I have no idea how your conversion tool will deal with the mathematica analytical methods of processing functions) then its just an evaluate, advance, re-evaluate.
jdaw1 wrote: 20:18 Tue 02 Jul 2019 • Don’t have the complicated lines. Instead have separate droplets, starting thin pale grey, ending thicker darker.
The darkness of this droplet should be normalised by, for a vector (potgridx and potgridy being the vector in question here) v=(x,y), |v|.
jdaw1 wrote: 20:18 Tue 02 Jul 2019 • Droplets advance in small steps downhill (2pt steps?), with no momentum.
• If consecutive steps have angle ≥10°, next step halved. (Or can optimal path length be deduced from second derivatives? Help!)
The size of the step should be normalised by the size of the vector to a first order (i.e.|v|) and the absolute of the first spatial derivative (i.e. |grad(v)|) to a second order. I think for this situation, the latter is the best option. As we already have potgrid calculated analytically, grad(potgrid) can also be calculated analytically, so I believe numerically calculating the second spatial derivative will not be required.

Much easier for me to say this than do it :roll:.
User avatar
jdaw1
Cockburn 1851
Posts: 23613
Joined: 15:03 Thu 21 Jun 2007
Location: London
Contact:

Re: Software that makes placemats

Post by jdaw1 »

akzy wrote: 11:00 Wed 03 Jul 2019This seems similar to what I proposed before
Sorry: hapy to acknowledge your prior art, and my slowness of understanding.
akzy wrote: 11:00 Wed 03 Jul 2019Providing your postscript code is fine with calculating potgrid analytically
It can.
akzy wrote: 11:00 Wed 03 Jul 2019just an evaluate, advance, re-evaluate.
Yes.
akzy wrote: 11:00 Wed 03 Jul 2019The darkness of this droplet should be normalised by, for a vector (potgridx and potgridy being the vector in question here) v=(x,y), |v|.
But then it’ll be intense black near charges, and pale grey away. I want a more even grey tone across the page.
akzy wrote: 11:00 Wed 03 Jul 2019The size of the step should be normalised by the size of the vector to a first order (i.e.|v|) and the absolute of the first spatial derivative (i.e. |grad(v)|) to a second order. I think for this situation, the latter is the best option.
You’re colouring by intensity of slope — i.e., dark near charges. But I want to choose step size by inverse curvature to lessen the number of “evaluate, advance, re-evaluate” steps. I suspect this will need ∇v.
akzy
Warre’s Otima 10 year old Tawny
Posts: 537
Joined: 21:42 Tue 13 Nov 2018
Location: Three Bridges

Re: Software that makes placemats

Post by akzy »

jdaw1 wrote: 07:48 Fri 05 Jul 2019
akzy wrote: 11:00 Wed 03 Jul 2019 Providing your postscript code is fine with calculating potgrid analytically
It can.
How? More of a curiosity thing than anything. Differentiating analytically using a computer is something I never fully understood (I'm still convinced that wolfram works using magic). If you know of any good explanations (or fancy trying yourself) please send them my way.
jdaw1 wrote: 07:48 Fri 05 Jul 2019
akzy wrote: 11:00 Wed 03 Jul 2019The darkness of this droplet should be normalised by, for a vector (potgridx and potgridy being the vector in question here) v=(x,y), |v|.
But then it’ll be intense black near charges, and pale grey away. I want a more even grey tone across the page.
My sneaky trick for all of these problems is to whack a logarithm on it somewhere. I had this exact problem trying to produce an electric field graphic for a paper - make the function logarithmic and everything looks better 88) .
jdaw1 wrote: 07:48 Fri 05 Jul 2019 You’re colouring by intensity of slope — i.e., dark near charges. But I want to choose step size by inverse curvature to lessen the number of “evaluate, advance, re-evaluate” steps. I suspect this will need ∇v.
I agree - ∇v is the way to do it. Higher orders wont help. The question is, what stepsize will it normalise? I think your 2pt idea seems to be a good plan followed by your interpolation of choice.
Post Reply