cancel
Showing results for
Show  only  | Search instead for
Did you mean:
JMP is taking Discovery online, April 16 and 18. Register today and join us for interactive sessions featuring popular presentation topics, networking, and discussions with the experts.
Submit your abstract to the call for content for Discovery Summit Americas by April 23. Selected abstracts will be presented at Discovery Summit, Oct. 21- 24.
Super User
Braid

JSL to make the images for this 4K 60 FPS animation attached.

The twisted links were fairly straightforward. Now I'm thinking about braids. There's a group bunch of mathematicians that are into braids. I learned just enough to be dangerous. Here's a little JSL to draw a five-strand braid. I believe all three variations in the picture below are equivalent.

``````drawpattern = Function( {pattern, gb},
channelToYPos = ["A" => 1, "B" => 2, "C" => 3, "D" => 4, "E" => 5]; // static
channelToStrandID = ["A" => 1, "B" => 2, "C" => 3, "D" => 4, "E" => 5]; // braiding swaps these around
strandIDToColor = Heat Color( (1 :: 5) / 6, "jet" );

erasecolor = gb[Framebox( 1 )] << getbackgroundcolor;

xleft = 1;
xstep = 1 / N Items( pattern );

circlesize = .20;
pensize = 15;

For( x = 1, x <= 10, x += 1,
For Each( {row}, pattern,
notfound = Associative Array( channelToYPos << getkeys );
For Each( {swapchans}, row,
channel_over = Substr( swapchans, 1, 1 );
channel_under = Substr( swapchans, 2, 1 );
// get Y positions of the two adjacent channels that will swap strands...
channel_over_ypos = channelToYPos[channel_over];
channel_under_ypos = channelToYPos[channel_under];
// get the strand ids currently in those channels
channel_over_StrandID = channelToStrandID[channel_over];
channel_under_StrandID = channelToStrandID[channel_under];
// get the colors of the strand ids
channel_over_Color = strandIDToColor[channel_over_StrandID];
channel_under_Color = strandIDToColor[channel_under_StrandID];
// render this swap
Pen Size( pensize );
Pen Color( channel_under_Color );
Line( {xleft, channel_under_ypos}, {xleft + xstep, channel_over_ypos} ); // draw under first
Fill Color( channel_under_Color );
Circle( {xleft, channel_under_ypos}, circlesize, "FILL" );
Pen Size( pensize * 2 - 1 );// erase a wider line before drawing to make the
Pen Color( erasecolor ); // overpass effect...
Line( {xleft, channel_over_ypos}, {xleft + xstep, channel_under_ypos} ); // draw over last, erase wider
Pen Size( pensize );
Pen Color( channel_over_Color );
Line( {xleft, channel_over_ypos}, {xleft + xstep, channel_under_ypos} ); // draw over last, within erased
Fill Color( channel_over_Color );
Circle( {xleft, channel_over_ypos}, circlesize, "FILL" );
// swap
channelToStrandID[channel_over] = channel_under_StrandID;
channelToStrandID[channel_under] = channel_over_StrandID;
notfound[channel_over] = 0;
notfound[channel_under] = 0;
);
For Each( {chan}, notfound,
ypos = channelToYPos[chan];
strandID = channelToStrandID[chan];
color = strandIDToColor[strandID];
Pen Size( pensize );
Pen Color( color );
Line( {xleft, ypos}, {xleft + xstep, ypos} ); // draw uncrossed strand
Fill Color( color );
Circle( {xleft, ypos}, circlesize, "FILL" );
);
xleft += xstep;
)
);
// endcaps, just for pretty
For Each( {chan, ypos}, channelToYPos,
strandID = channelToStrandID[chan];
color = strandIDToColor[strandID];
Fill Color( color );
Circle( {xleft, ypos}, circlesize, "FILL" );
);
);

New Window( "braidtest",
V List Box(
window:gb1 = Graph Box(
X Scale( 0, 12 ),
Y Scale( 0, 6 ),
framesize( 1800, 300 ),
xname( "" ),
yname( "" ),
suppressaxes,
<<backgroundcolor( "black" ),
drawpattern( {{"CB", "ED"}, {"CD", "AB"}}, window:gb1 );// twist:{"CD", "AB"}, {"DE", "BC"}
),
window:gb2 = Graph Box(
X Scale( 0, 12 ),
Y Scale( 0, 6 ),
framesize( 1800, 300 ),
xname( "" ),
yname( "" ),
suppressaxes,
<<backgroundcolor( "black" ),
drawpattern( {{"CB"}, {"AB", "ED"},  {"CD"}}, window:gb2 );
),
window:gb3 = Graph Box(
X Scale( 0, 12 ),
Y Scale( 0, 6 ),
framesize( 1800, 300 ),
xname( "" ),
yname( "" ),
suppressaxes,
<<backgroundcolor( "black" ),
drawpattern( { {"CB"}, {"ED"}, {"CD"}, {"AB"}}, window:gb3 );
)
)
);``````

The JSL is using channels A, B, C, D, E to refer to the straight horizontal rows and strands 1, 2, 3, 4, 5 to refer to the five colorful strings that dart back and forth between the channels, passing over/below another string. The three variations are defined by a pattern; the middle one is

``drawpattern( {{"CB"}, {"AB", "ED"},  {"CD"}}, window:gb2 );``

which means channels C and B swap strands with the strand from C passing over the strand from B. Then channel A passes above B simultaneously with channel E passing above D.  Finally, swap C and D, again with C above.

Colorful braids. The top one is smoothest.

If you run the attached code, change AntiAlias = 4 to AntiAlias = 1 to run it faster until you want the high quality images.