timeStretchFactor for individual throws in JIF

70 views
Skip to first unread message

Carl Hunt

unread,
Mar 23, 2022, 8:29:05 PM3/23/22
to juggling-interchange-format
Hi,

First off I'd like to thank Christian Helbling for his wonderful application passist and proposing Juggling Interchange Format (JIF). Thanks, Christian!

I'm the advisor for a university-based juggling club and haven't been juggling with the club for almost two years. I met up with a few members recently and struggled to remember one of the patterns we used to do. I thought it would be a good idea to create some videos to serve as tutorials in my absence (and to help my memory in the future). I considered JoePass and Jongl and finally found passist which seemed easier for me to work with.

I'm not a siteswap expert and it took me a few tries but I think I finally have a halfway decent generator whose output is JIF throws. You can see Christian helping me out in this github issue. A lot of the patterns I juggle and create have hurries in them. In my JIF throws these ended up needing to be 2's and 4's to get the rhythm right and satisfy the siteswap math but in practice they are thrown slower or faster (respectively) to keep in time with the other throws in the pattern.

For example, this is a relatively simple pattern that we call in my juggling club "4-count fls" (read "four count floss") where fls stands for "flip last self". In words it's "pass, self, self, flip" and the rhythm is RLRLLRLR.

https://user-images.githubusercontent.com/2301586/159362824-072b25bf-acec-4d1c-b292-3042c022c4b9.mp4

I adjusted the timing to be more what it's like in practice in this video:

https://user-images.githubusercontent.com/2301586/159540076-5f893d42-055e-4c68-9114-9826a4e3a743.mp4

To do that I used a throwTimeStretchFactorPermutation in my generator which puts in a timeStretchFactor attribute for each throw (and adjusted the animation use that, multiplied by the global timeStretchFactor). I know that some previous posts may have discussed timing but this seems like a relatively simple addition to JIF. What do you think?

Another question I have is, is there a place to see JIF files in the wild besides https://github.com/helbling/passist/tree/main/tests/jif?

Thanks!

Carl Hunt

unread,
Mar 23, 2022, 8:42:53 PM3/23/22
to juggling-interchange-format

Christian Helbling

unread,
Mar 24, 2022, 4:12:29 PM3/24/22
to juggling-inte...@googlegroups.com
Hi Carl

On 24.03.22 01:29, Carl Hunt wrote:
> Hi,
>
> First off I'd like to thank Christian Helbling for his wonderful application passist and proposing Juggling Interchange Format (JIF). Thanks, Christian!
You're welcome!

> I'm the advisor for a university-based juggling club and haven't been juggling with the club for almost two years. I met up with a few members
> recently and struggled to remember one of the patterns we used to do. I thought it would be a good idea to create some videos to serve as tutorials in
> my absence (and to help my memory in the future). I considered JoePass and Jongl and finally found passist which seemed easier for me to work with.
Glad you like it. I still have a lot to do to reach the level of the existing animators, though :)

> I'm not a siteswap expert and it took me a few tries but I think I finally have a halfway decent generator whose output is JIF throws. You can see
> Christian helping me out in this github issue <https://github.com/helbling/passist/issues/18>. A lot of the patterns I juggle and create have hurries
> in them. In my JIF throws these ended up needing to be 2's and 4's to get the rhythm right and satisfy the siteswap math but in practice they are
> thrown slower or faster (respectively) to keep in time with the other throws in the pattern.
>
> For example, this is a relatively simple pattern that we call in my juggling club "4-count fls" (read "four count floss") where fls stands for "flip
> last self". In words it's "pass, self, self, flip" and the rhythm is RLRLLRLR.
>
> https://user-images.githubusercontent.com/2301586/159362824-072b25bf-acec-4d1c-b292-3042c022c4b9.mp4
> <https://user-images.githubusercontent.com/2301586/159362824-072b25bf-acec-4d1c-b292-3042c022c4b9.mp4>
>
> I adjusted the timing to be more what it's like in practice in this video:
>
> https://user-images.githubusercontent.com/2301586/159540076-5f893d42-055e-4c68-9114-9826a4e3a743.mp4
> <https://user-images.githubusercontent.com/2301586/159540076-5f893d42-055e-4c68-9114-9826a4e3a743.mp4>
>
> To do that I used a throwTimeStretchFactorPermutation in my generator which puts in a timeStretchFactor attribute for each throw (and adjusted the
> animation use that, multiplied by the global timeStretchFactor). I know that some previous posts may have discussed timing but this seems like a
> relatively simple addition to JIF. What do you think?

I'm not quite sure if I understand you correctly what this timeStretchFactor per throw should do exactly. Should it adjust the throw duration?

We're trying to keep the JIF format as simple as possible.
If this just adjusts some timings, this seems unnecessarily to me.
Otherwise: can you provide a minimal example of a pattern using your version compared to mine?


BTW: Have you seen, that you can use floating-point values for time and duration?


I've seen you generated quite a long sequence of throws. I suppose the main reason for that is,
that you calculated the prop used per throw.
This is usually not needed and can be calculated by the animator itself. In your pattern this should
be unambiguous. An example where it would make sense to specify the props explicitly is a multiplex
pattern, where you care which prop goes where.
Without explicit prop assignments, your period should be much shorter.


> Another question I have is, is there a place to see JIF files in the wild besides https://github.com/helbling/passist/tree/main/tests/jif
> <https://github.com/helbling/passist/tree/main/tests/jif>?

You're probably a bit early for that, as we haven't fully specified JIF yet. A lot of things are still in discussion, even things included in
my files you found. I'm still trying things out. Sometimes I have to rewrite the example files to my newest draft. Thereby I hope to get a feeling
how practical some idea is.

There is currently only a few things definitely decided. See Chapter Decisions here:
https://github.com/helbling/jif

Some of the concepts in my draft are a bit more settled (I think):
- jugglers
- limbs
- props
- throws

I'm currently trying to get some extended siteswap syntax running (described here: https://jugglinglab.org/html/ssnotation.html).
It turned out, that my idea of propPermutation (see https://groups.google.com/g/juggling-interchange-format/c/_joONqzVNqQ)
was not too practical. I still need to think this through, hopefully find a better proposal, and write my findings to the list.
Therefore, I would not consider the repetition section stable in any way :)


Nevertheless, someone on this list might have generated some jif files, which might or might not be similar to mine.
So your question is still valid and it is certainly interesting how the jif files of other patterns and other jif-drafts look like.


> Thanks!
Thank you for your interest.
Its good to get the discussions started again and I'm looking forward to get the JIF-specification to the next level.

Cheers
Christian



Carl Hunt

unread,
Mar 24, 2022, 9:59:53 PM3/24/22
to juggling-interchange-format
Thanks for your response!

> I'm not quite sure if I understand you correctly what this timeStretchFactor per throw should do exactly. Should it adjust the throw duration?

I put some new videos and JIF files on https://github.com/helbling/passist/issues/18. The first pair of videos show 4-count with diagonal passes (diagonal pass, self, self, self).



The second pair of videos show one person doing 4-count fls (pass, self, self, flip) and one person doing 4-count with diagonal passes (diagonal pass, self, self, self).


For the second video in each pair I set an individual timeStretchFactor and used it in this way in animation.js:

throwTimeStretchFactor.png

> We're trying to keep the JIF format as simple as possible.
> If this just adjusts some timings, this seems unnecessarily to me.
> Otherwise: can you provide a minimal example of a pattern using your version compared to mine?

The JIF files are:


The first 8 throws of each define the pattern (outside of props) but I don't know how to make it smaller and still animate properly.

> BTW: Have you seen, that you can use floating-point values for time and duration?

I didn't realize that. Thanks!


> I've seen you generated quite a long sequence of throws. I suppose the main reason for that is,
> that you calculated the prop used per throw.
> This is usually not needed and can be calculated by the animator itself. In your pattern this should
> be unambiguous. An example where it would make sense to specify the props explicitly is a multiplex
> pattern, where you care which prop goes where.
> Without explicit prop assignments, your period should be much shorter.

I couldn't figure out how to create short versions and have it animate properly. Is there a JIF file for regular two juggler, six club 4-count (pass, self, self, self)? I worked this out by hand initially (with many mistakes!) and then wrote a generator I could use to output the full JIF file from a shortened version I could understand. I don't fully understand what repetition.limbPermutation is supposed to be. I also spent a couple hours trying to work out the patterns on https://jugglinglab.org/html/animinfo.html with no success. It's easier for me to create the long-version JIF file which works and produces a nice animation.

Lukas Bonauer

unread,
Mar 25, 2022, 7:21:26 AM3/25/22
to juggling-inte...@googlegroups.com, waaa...@gmail.com

Hey all,

great to see JIF discussions popping up again! Sadly don't have time right now for detailed thoughts, but regarding examples I wanted to mention my repository where I experimented a bit with JIF.

There are 2 main features that worked out reasonably well:

- Generate JIF from high level passing descriptions (a social siteswap string, e.g. ["3B 3 3", "3A 3 3"] for 3-count).
- Programmatically add manipulator instructions to a pattern (and analyze prop orbits).

https://github.com/Bone008/jif-playground

I don't have a lot of example files in the repo yet, but you can find some expected outputs in the unit tests. Note that I used a more minimalist subset of JIF than Christian, my names do not match exactly, and I wanted to try out my proposal of "everything is optional".

Ideally though, the end goal is that you could throw the output of my generator into passist to animate manipulator patterns :)


That being said, I am also not sure if I understand per throw "timeStretchFactor". Sounds like something that should be solvable by adjusting either dwell time or either fractional throw durations (or by multiplying all times with the lowest common divisor).

(Also, I have never heard of the "flip last self" pattern family and it sounds pretty cool, would love to try it out someday!)

Cheers,
Lukas

Carl Hunt

unread,
Mar 26, 2022, 6:57:49 PM3/26/22
to juggling-interchange-format
Hi, Lukas! Thanks for the response! I checked out https://github.com/Bone008/jif-playground and it's great! Your DATA_4_COUNT_PASSING example gave me the minimal code I needed to see so I could put my patterns into minimal JIF. The ones under discussion are "4-count fls":
=====
{
  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 8
  },
  "throws": [
    { "time": 0, "duration": 3, "from": 0, "to": 3},
    { "time": 1, "duration": 4, "from": 1, "to": 0},
    { "time": 2, "duration": 2, "from": 0, "to": 1},
    { "time": 3, "duration": 3, "from": 1, "to": 1},
    { "time": 4, "duration": 3, "from": 1, "to": 2},
    { "time": 5, "duration": 4, "from": 0, "to": 1},
    { "time": 6, "duration": 2, "from": 1, "to": 0},
    { "time": 7, "duration": 3, "from": 0, "to": 0},
    { "time": 0, "duration": 3, "from": 2, "to": 1},
    { "time": 1, "duration": 4, "from": 3, "to": 2},
    { "time": 2, "duration": 2, "from": 2, "to": 3},
    { "time": 3, "duration": 3, "from": 3, "to": 3},
    { "time": 4, "duration": 3, "from": 3, "to": 0},
    { "time": 5, "duration": 4, "from": 2, "to": 3},
    { "time": 6, "duration": 2, "from": 3, "to": 2},
    { "time": 7, "duration": 3, "from": 2, "to": 2}
 ]
}
=====
And "4-count with diagonal passes":
=====
{
  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 8
  },
  "throws": [
    { "time": 0, "duration": 3, "from": 1, "to": 3},
    { "time": 1, "duration": 3, "from": 1, "to": 0},
    { "time": 2, "duration": 4, "from": 0, "to": 1},
    { "time": 3, "duration": 2, "from": 1, "to": 0},
    { "time": 4, "duration": 3, "from": 0, "to": 2},
    { "time": 5, "duration": 3, "from": 0, "to": 1},
    { "time": 6, "duration": 4, "from": 1, "to": 0},
    { "time": 7, "duration": 2, "from": 0, "to": 1},
    { "time": 0, "duration": 3, "from": 3, "to": 1},
    { "time": 1, "duration": 3, "from": 3, "to": 2},
    { "time": 2, "duration": 4, "from": 2, "to": 3},
    { "time": 3, "duration": 2, "from": 3, "to": 2},
    { "time": 4, "duration": 3, "from": 2, "to": 0},
    { "time": 5, "duration": 3, "from": 2, "to": 3},
    { "time": 6, "duration": 4, "from": 3, "to": 2},
    { "time": 7, "duration": 2, "from": 2, "to": 3}
 ]
}
=====
This format makes it particularly easy to combine them into this pattern where one juggler is doing 4-count fls and the other is doing 4-count with diagonal passes (just swap out one juggler's throws in the other pattern):
=====
{
  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 8
  },
  "throws": [
    { "time": 0, "duration": 3, "from": 0, "to": 3},
    { "time": 1, "duration": 4, "from": 1, "to": 0},
    { "time": 2, "duration": 2, "from": 0, "to": 1},
    { "time": 3, "duration": 3, "from": 1, "to": 1},
    { "time": 4, "duration": 3, "from": 1, "to": 2},
    { "time": 5, "duration": 4, "from": 0, "to": 1},
    { "time": 6, "duration": 2, "from": 1, "to": 0},
    { "time": 7, "duration": 3, "from": 0, "to": 0},
    { "time": 0, "duration": 3, "from": 3, "to": 1},
    { "time": 1, "duration": 3, "from": 3, "to": 2},
    { "time": 2, "duration": 4, "from": 2, "to": 3},
    { "time": 3, "duration": 2, "from": 3, "to": 2},
    { "time": 4, "duration": 3, "from": 2, "to": 0},
    { "time": 5, "duration": 3, "from": 2, "to": 3},
    { "time": 6, "duration": 4, "from": 3, "to": 2},
    { "time": 7, "duration": 2, "from": 2, "to": 3}
 ]
}
=====

Going back to your "social siteswap" notation it should be something like (if x throws were allowed):

4-count fls: [ '3B 4x 2x 3x', '3A 4x 2x 3x' ]
4-count with diagonal passes (start left): [ '3xB 3 4x 2x', '3xA 3 4x 2x' ]

Mixed 4-count fls and diagonal passes (juggler doing diagonal passes starts left): [ '3B 4x 2x 3x', '3xA 3 4x 2x' ]
This is what I like about JIF so much. It lets me do arbitrary x throws (not restricted to even numbers).

However, I still have an issue with timing and/or height. If we look at either [ '3B 4x 2x 3x', '3A 4x 2x 3x' ] or [ '3xB 3 4x 2x', '3xA 3 4x 2x' ]
ideally we want each throw to take about the same time (i.e, each throw is thrown on the beat of someone counting "one, two, three, four").
So the 2x throws need to be higher/slower to match a regular 3 throw and the 4x throws need to be shorter/faster to match a regular 3 throw.
That's what I was trying to do with an individual throw timeStretchFactor.

Christian Helbling

unread,
Mar 27, 2022, 9:15:15 AM3/27/22
to juggling-inte...@googlegroups.com
Hi

On 25.03.22 12:21, 'Lukas Bonauer' via juggling-interchange-format wrote:
> That being said, I am also not sure if I understand per throw "timeStretchFactor". Sounds like something that should be solvable by adjusting either
> dwell time or either fractional throw durations (or by multiplying all times with the lowest common divisor).
>
On 26.03.22 23:57, Carl Hunt wrote:
> However, I still have an issue with timing and/or height. If we look at either [ '3B 4x 2x 3x', '3A 4x 2x 3x' ] or [ '3xB 3 4x 2x', '3xA 3 4x 2x' ]
> ideally we want each throw to take about the same time (i.e, each throw is thrown on the beat of someone counting "one, two, three, four").
> So the 2x throws need to be higher/slower to match a regular 3 throw and the 4x throws need to be shorter/faster to match a regular 3 throw.
> That's what I was trying to do with an individual throw timeStretchFactor.

I think Lukas is right here.
One option is to adjust throw durations. You are not limited to restrictions of siteswap/prechac and whole numbers here.
You can also add some holds of arbitrary length when specifying the same hand as from and to.

The other option is explicitly specifying dwell times or exact throwTime/catchTime.
If the exact throwTime and catchTime are specified, the height is given by physics.
However, we still haven't agreed on the specifications here and passist has currently no support for that yet.
But it's something that will definitly be specified in JIF in one form or another.


There's already a lengthy discussion here:
https://groups.google.com/g/juggling-interchange-format/c/LKG37GRn7I4


I'll try to make a summary - correct me if I'm wrong, or if I missed some major point:

1. We want to be able to represent patterns as ladder/causal diagrams (https://en.wikipedia.org/wiki/Juggling_notation#Diagram-based)
and animators should have some heuristics about filling in default dwell times themselves

2. It is not that clear where such default dwell times should be added.
A throw { time:5, duration:3 } with a default dwell time of, say, 1, for example could be converted to
a) throwTime:5, catchTime:7 - "throw on the beat"
b) throwTime:6, catchTime:8 - "catch on the beat"
c) something in-between, like: throwTime:5.5, catchTime:7.5

It is not clear, which of these options should be the default.
It is not clear, if one should be able to set "throw on the beat" or "catch on the beat" globally.

3. We want to be able to explicitly specify exact throw/catch times (dwell times and duration/height can be calculated from them).

4. There is a proposal to combine 1. with 3.:

Only specify causal/ladder diagram:
throws = [
{time:0, height:5, from:0, to:1},
{time:1, height:3, from:1, to:0},
{time:2, height:1, from:0, to:1},
{time:3, height:5, from:1, to:0},
{time:4, height:3, from:0, to:1},
{time:5, height:1, from:1, to:0},
]

extended to include exact throw and catch times (throwTime := time + throwOffset):
throws = [
{time:0, height:5, catchTime:4, from:0, to:1},
{time:1, height:3, catchTime:3, from:1, to:0},
{time:2, height:1, catchTime:2, from:0, to:1, throwOffset;-0.5},
{time:3, height:5, catchTime:7, from:1, to:0},
{time:4, height:3, catchTime:6, from:0, to:1},
{time:5, height:1, catchTime:5, from:1, to:0, throwOffset:-0.5},
]

> <ad.gol...@gmail.com>:
> Here the time, height, from/toHand are used for the logical layer and the physical layer adds the fact that there's always 1 beat of dwell time
(through the catchTimes - maybe that should be entered using dwell instead but they're equivalent so I just chose randomly for now) and that the 1s
are thrown early so they have nonzero flight time. If catchTime and throwOffset are left blank then simulators can use smart defaults to make things
look good (like most simulators already do) or we can define some JIF recommended smart defaults (e.g. 1 dwell beat and zips have a throw offset of
-0.5, the rest have a throwOffset of 0). To describe Throw_On_The_Beat, we'd set throwOffset=0 and catchTime=1.5 and 4.5 for the zips.
> My main issue with this at the moment is just that they can still get slightly out of sync (the throwOffset can be anything really), however it's
at least explicitly tied to the time.


5. An idea that we only specify exact throw and catch times (3.).
This makes problem 2 something converters should do themselves, possibly using options.
And problem 1 might be solvable by causal viewers.

>> I have some worry that half of the programmers will only animate throw-on-the-beat.
> <ad.gol...@gmail.com>:
> This is a fair point, however in my version you can still 'force' them to do it properly by setting the times like I did above, the main issue is
that it's now harder to extract the original siteswap, but I don't think we should optimise for that as it should be a rare thing to do.
> Though this is kind of making me think that we shouldn't have a throwOffset at all, and maybe just use the actual time, yes this will mean that
unless you modify timing explicitly (which seems OK seeing as you want throw vs catch on beat visible on the causal) converting from a causal will by
default give throw-on-the-beat, we can have converters from siteswaps that have options for all of this (and smart defaults) however. This would also
avoid animators doing a bad job at this because it would always be specified explicitly. I feel like this is very much heading towards JML's way of
only specifying throw/catch times (i.e. only the physical layer) and maybe that's the way to go, because siteswaps technically only care about order,
you can normally extract them back out, and causals always specify exact throw times so it's only the awkward part of extracting the causal chain that
needs to be done here (which is a problem causal viewers would need to solve anyway IMO), the issue with this would be that simple patterns are more
complex - I don't know if that's a reasonable tradeoff.


The discussion is still open.


I don't have a favorite solution to this yet.
Idea 5 would certainly make the format much simpler and avoids a lot of specification problems by moving them into the implementations.
I'm still a bit uncertain about the implications for the causal viewer code and other things. But I'll think about it.


Cheers
Christian

Carl Hunt

unread,
Mar 27, 2022, 9:24:31 PM3/27/22
to juggling-interchange-format
Thanks for the explanation! I look forward to the completion of the specification. There's enough in it now that I can start documenting my patterns in earnest. I'm planning to use a mantra-based notation that I can translate into the current JIF spec now. Then when the full specification is determined I can modify my translator and regenerate the JIF versions.

I'm not sure I understand not using whole numbers. Do you have any examples of that? I'm wondering if that might be where you do things like slow-fasts and hand-acrosses. For instance, what would be the JIF version of this pattern:

A: slow 4-count (pass, self, self, self, diagonal-pass, self, self, self) - passes to B alternate limbs
B: fast 3-count (pass, self, self,       diagonal-pass, self, self) - passes to A are to the right limb

I've also seen the multi-handed version of Mild Madness (7777266). This has the right order of the throws but the timing is very far off of what is actually juggled. To my mind, pass-hand-across, is a "single beat" throw and I incorporate it into patterns in that way. Do you know what the JIF file for Mild Madness would be if you set the global timeStretchFactor to 1 one and synchronized "time" for each juggler (i.e., time 0, time 0, time 1, time 1 instead of time 0, time 1, time 2, time 3)? When I teach the pattern in my juggling club I use this mantra:

A (mild): pass, pass-hand-across, self, pass, pass, self
B (mad):  diagonal-pass, diagonal-pass, self, diagonal-pass, diagonal-pass-hand-across, self

In case it helps the discussion I worked out this JIF version (global timeStretchFactor 1, synchronized throws) of Jim's 3-count as:
=====
{
  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 12
  },
  "throws": [
    { "time": 0, "duration": 3, "from": 0, "to": 3},
    { "time": 1, "duration": 3, "from": 0, "to": 1},
    { "time": 2, "duration": 3, "from": 1, "to": 0},
    { "time": 3, "duration": 3, "from": 0, "to": 3},
    { "time": 4, "duration": 4, "from": 1, "to": 0},
    { "time": 5, "duration": 2, "from": 0, "to": 1},
    { "time": 6, "duration": 3, "from": 1, "to": 2},
    { "time": 7, "duration": 3, "from": 1, "to": 0},
    { "time": 8, "duration": 3, "from": 0, "to": 1},
    { "time": 9, "duration": 3, "from": 1, "to": 2},
    { "time": 10, "duration": 4, "from": 0, "to": 1},
    { "time": 11, "duration": 2, "from": 1, "to": 0},
    { "time": 0, "duration": 3, "from": 2, "to": 0},
    { "time": 1, "duration": 4, "from": 3, "to": 2},
    { "time": 2, "duration": 2, "from": 2, "to": 3},
    { "time": 3, "duration": 3, "from": 3, "to": 1},
    { "time": 4, "duration": 3, "from": 3, "to": 2},
    { "time": 5, "duration": 3, "from": 2, "to": 3},
    { "time": 6, "duration": 3, "from": 3, "to": 1},
    { "time": 7, "duration": 4, "from": 2, "to": 3},
    { "time": 8, "duration": 2, "from": 3, "to": 2},
    { "time": 9, "duration": 3, "from": 2, "to": 0},
    { "time": 10, "duration": 3, "from": 2, "to": 3},
    { "time": 11, "duration": 3, "from": 3, "to": 2}
 ]
}
=====
The mantra is:
A (mild): pass, self, self
B (mad):  diagonal-pass, self, self

Carl Hunt

unread,
Mar 28, 2022, 9:13:17 PM3/28/22
to juggling-interchange-format
I'm not sure if it helps but I found an individual dwell gives me a similar effect.

4-count fls:
=====
{
  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 8

  },
  "throws": [
    { "time": 0, "duration": 3, "from": 0, "to": 3 },
    { "time": 1, "duration": 4, "spins": 1, "dwell": 1.9, "from": 1, "to": 0 },
    { "time": 2, "duration": 2, "spins": 1, "dwell": 0.2, "from": 0, "to": 1 },
    { "time": 3, "duration": 3, "from": 1, "to": 1 },
    { "time": 4, "duration": 3, "from": 1, "to": 2 },
    { "time": 5, "duration": 4, "spins": 1, "dwell": 1.9, "from": 0, "to": 1 },
    { "time": 6, "duration": 2, "spins": 1, "dwell": 0.2, "from": 1, "to": 0 },
    { "time": 7, "duration": 3, "from": 0, "to": 0 },
    { "time": 0, "duration": 3, "from": 2, "to": 1 },
    { "time": 1, "duration": 4, "spins": 1, "dwell": 1.9, "from": 3, "to": 2 },
    { "time": 2, "duration": 2, "spins": 1, "dwell": 0.2, "from": 2, "to": 3 },
    { "time": 3, "duration": 3, "from": 3, "to": 3 },
    { "time": 4, "duration": 3, "from": 3, "to": 0 },
    { "time": 5, "duration": 4, "spins": 1, "dwell": 1.9, "from": 2, "to": 3 },
    { "time": 6, "duration": 2, "spins": 1, "dwell": 0.2, "from": 3, "to": 2 },
    { "time": 7, "duration": 3, "from": 2, "to": 2}
 ]
}
=====
Jim's 3-count:
=====
{
  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 12
  },
  "throws": [
    { "time": 0, "duration": 3, "from": 0, "to": 3},
    { "time": 1, "duration": 3, "from": 0, "to": 1},
    { "time": 2, "duration": 3, "from": 1, "to": 0},
    { "time": 3, "duration": 3, "from": 0, "to": 3},
    { "time": 4, "duration": 4, "spins": 1, "dwell": 1.9, "from": 1, "to": 0},
    { "time": 5, "duration": 2, "spins": 1, "dwell": 0.2, "from": 0, "to": 1},

    { "time": 6, "duration": 3, "from": 1, "to": 2},
    { "time": 7, "duration": 3, "from": 1, "to": 0},
    { "time": 8, "duration": 3, "from": 0, "to": 1},
    { "time": 9, "duration": 3, "from": 1, "to": 2},
    { "time": 10, "duration": 4, "spins": 1, "dwell": 1.9, "from": 0, "to": 1},
    { "time": 11, "duration": 2, "spins": 1, "dwell": 0.2, "from": 1, "to": 0},

    { "time": 0, "duration": 3, "from": 2, "to": 0},
    { "time": 1, "duration": 4, "spins": 1, "dwell": 1.9, "from": 3, "to": 2},
    { "time": 2, "duration": 2, "spins": 1, "dwell": 0.2, "from": 2, "to": 3},

    { "time": 3, "duration": 3, "from": 3, "to": 1},
    { "time": 4, "duration": 3, "from": 3, "to": 2},
    { "time": 5, "duration": 3, "from": 2, "to": 3},
    { "time": 6, "duration": 3, "from": 3, "to": 1},
    { "time": 7, "duration": 4, "spins": 1, "dwell": 1.9, "from": 2, "to": 3},
    { "time": 8, "duration": 2, "spins": 1, "dwell": 0.2, "from": 3, "to": 2},

    { "time": 9, "duration": 3, "from": 2, "to": 0},
    { "time": 10, "duration": 3, "from": 2, "to": 3},
    { "time": 11, "duration": 3, "from": 3, "to": 2}
 ]
}
=====

Christian Helbling

unread,
Mar 29, 2022, 3:32:12 PM3/29/22
to juggling-inte...@googlegroups.com
Hi Carl

On 28.03.22 03:24, Carl Hunt wrote:
> [..]
> I'm not sure I understand not using whole numbers. Do you have any examples of that? I'm wondering if that might be where you do things like
> slow-fasts and hand-acrosses. For instance, what would be the JIF version of this pattern:
>
> A: slow 4-count (pass, self, self, self, diagonal-pass, self, self, self) - passes to B alternate limbs
> B: fast 3-count (pass, self, self,       diagonal-pass, self, self) - passes to A are to the right limb

Yes, exactly.
Apart from exact dwell times and time-scaling this could look something like this:

{
"limbs": [
{ "juggler": 0, "type": "right hand" },
{ "juggler": 0, "type": "left hand" },
{ "juggler": 1, "type": "right hand" },
{ "juggler": 1, "type": "left hand" }
],
"repetition": {
"period": 4,
"limbPermutation": [0, 1, 3, 2]
},
"throws": [
{ "time": 0, "duration": 4, "from": 0, "to": 3, "spins": 1, "label": "pass" },
{ "time": 1, "duration": 3, "from": 1, "to": 0, "spins": 1, "label": "self" },
{ "time": 2, "duration": 3, "from": 0, "to": 1, "spins": 1, "label": "self" },
{ "time": 3, "duration": 3, "from": 1, "to": 0, "spins": 1, "label": "self" },

{ "time": 0, "duration": 3, "from": 2, "to": 1, "spins": 1, "label": "pass" },
{ "time": 1.33, "duration": 4, "from": 3, "to": 2, "spins": 1, "label": "self" },
{ "time": 2.66, "duration": 4, "from": 2, "to": 3, "spins": 1, "label": "self" }
]
}

NOTE: the limbPermutation here means: swap hands 2 and 3 on every repetition.
this makes A alternate its pass target hands and B will switch its hands but still throw to A's left hand.

Without that, you'll have period 8 and would need to specify double as many throws.


> I've also seen the multi-handed version of Mild Madness (7777266). This has the right order of the throws but the timing is very far off of what is
> actually juggled. To my mind, pass-hand-across, is a "single beat" throw and I incorporate it into patterns in that way. Do you know what the JIF file
> for Mild Madness would be if you set the global timeStretchFactor to 1 one and synchronized "time" for each juggler (i.e., time 0, time 0, time 1,
> time 1 instead of time 0, time 1, time 2, time 3)? When I teach the pattern in my juggling club I use this mantra:
>
> A (mild): pass, pass-hand-across, self, pass, pass, self
> B (mad):  diagonal-pass, diagonal-pass, self, diagonal-pass, diagonal-pass-hand-across, self

This was a tricky one, needed quite some time for it :)

{
"limbs": [
{ "juggler": 0, "type": "right hand" },
{ "juggler": 0, "type": "left hand" },
{ "juggler": 1, "type": "right hand" },
{ "juggler": 1, "type": "left hand" }
],
"repetition": {
"period": 3,
"limbPermutation": [ 3, 2, 0, 1 ]
},
"throws": [
{ "time": 0, "duration": 3, "from": 0, "to": 3, "spins":1, "label": "pass"},
{ "time": 0, "duration": 3, "from": 2, "to": 0, "spins":1, "label": "pass"},

{ "time": 1, "duration": 3, "from": 1, "to": 2, "spins":1, "label": "pass"},
{ "time": 1, "duration": 1, "from": 0, "to": 1, "spins":0, "label": "zip"},
{ "time": 1, "duration": 3, "from": 3, "to": 1, "spins":1, "label": "pass"},

{ "time": 2, "duration": 3, "from": 1, "to": 0, "spins":1, "label": "self"},
{ "time": 2, "duration": 2, "from": 2, "to": 3, "spins":1, "label": "self"}
]
}

limbPermutation here makes the limbs do the following transistion on every repetition:
0 -> 3 -> 1 -> 2 -> 0
without it, 4 times as many throws would need to be specified.

To fine-tune you can set some explicit dwell times here as well.

Cheers
Christian

Carl Hunt

unread,
Mar 30, 2022, 10:01:58 PM3/30/22
to juggling-interchange-format
Thanks, Christian! These are elegant solutions. I didn't really understand limbPermutation before but now it
makes more sense. Every fls (flip last self) pattern should have a limbPermutation of [1, 0, 3, 2]:
=====
{

  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 4,
    "limbPermutation": [1, 0, 3, 2]
  },
  "throws": [
    { "time": 0, "duration": 3, "spins": 1, "from": 0, "to": 3},
    { "time": 1, "duration": 4, "spins": 1, "from": 1, "to": 0},
    { "time": 2, "duration": 2, "spins": 1, "from": 0, "to": 1},
    { "time": 3, "duration": 3, "spins": 1, "from": 1, "to": 1},

    { "time": 0, "duration": 3, "spins": 1, "from": 2, "to": 1},
    { "time": 1, "duration": 4, "spins": 1, "from": 3, "to": 2},
    { "time": 2, "duration": 2, "spins": 1, "from": 2, "to": 3},
    { "time": 3, "duration": 3, "spins": 1, "from": 3, "to": 3}
 ]
}
=====
From your example I worked out the 3,2 slowfast:
=====
{

  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 3,
    "limbPermutation": [1, 0, 2, 3]
  },
  "throws": [
    { "time": 0, "duration": 4, "spins": 1, "from": 0, "to": 3},
    { "time": 1, "duration": 3, "from": 1, "to": 0},
    { "time": 2, "duration": 3, "from": 0, "to": 1},


    { "time": 0, "duration": 3, "from": 2, "to": 1},
    { "time": 1.5, "duration": 4, "spins": 1, "from": 3, "to": 2}
 ]
}
=====
And the 2,3 slowfast:
=====
{

  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 3,
    "limbPermutation": [0, 1, 3, 2]
  },
  "throws": [
    { "time": 0, "duration": 3, "spins": 1, "from": 0, "to": 3},
    { "time": 1, "duration": 4, "spins": 1, "from": 1, "to": 0},

    { "time": 0, "duration": 4, "spins": 1, "from": 2, "to": 1},
    { "time": 0.66, "duration": 3, "spins": 1, "from": 3, "to": 2},
    { "time": 1.32, "duration": 3, "spins": 1, "from": 2, "to": 3}
 ]
}
=====
For this last one I'd like to be able to add insert 2 self throws to each juggler's pattern and the result
should be a pattern compatible with 4-count fls but I can't figure it out. I keep getting more than
6 props.The mantra would be something like "pass, self, self-self-self in two beats". This would be
compatible with "pass, self, double throw to the alternate hand" but that one is stumping me, too.

In a similar way, for Mild Madness I should be able to add a self throw at the end but I can't get that
to work out, either:

A (mild): pass, pass-zip, self, self, pass, pass, self, self
B (mad):  diagonal-pass, diagonal-pass, self, self, diagonal-pass, diagonal-pass-zip, self, self

I think I know enough now to work out my mammoth "Jim's Jamboree" pattern (where each juggler
cycles through the four variations of Jim's Jam out of phase). If I can get the zips down better I can work
on my other big pattern which I call "Bill and Carl's Chocolatada" (or just Chocolatada for short). That's
when each juggler cycles through the four variations of chocolate bar fls (pass, pass, self, flip) out of
phase.

I'll keep working on it. Thanks for all your help!

JaCo Stuifbergen

unread,
Apr 1, 2022, 11:26:36 AM4/1/22
to juggling-interchange-format
A note about the 2,3 slowfast:

I think that the period should be 2, not 3. (you press 3 throws in 2 counts).

For the quick juggler, durations should be 2, except the passes.

 (and for adequate rounding of the fractions: 2/3 = 0.67 , 4/3 = 1.33)

I think that this will yield a ladder diagram without gaps etc:
=========
2,3 slowfast:
=====

{
  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 2,

    "limbPermutation": [0, 1, 3, 2]
  },
  "throws": [
    { "time": 0, "duration": 2, "spins": 1, "from": 0, "to": 3},
    { "time": 1, "duration": 3, "spins": 1, "from": 1, "to": 0},


    { "time": 0, "duration": 3, "spins": 1, "from": 2, "to": 1},
    { "time": 0.67, "duration": 2, "spins": 1, "from": 3, "to": 2},
    { "time": 1.33, "duration": 2, "spins": 1, "from": 2, "to": 3}
 ], "timeStretchFactor":0.7
}
-----------------------------------
note: I have set timeStretchFactor < 1, to slow the pattern down in the animator.
===================
For mathematical pureness, if you want to set a fraction like 2/3 in stead of 0.66, you can multiply all the times, durations and dwell times and the period by 3, and set TimeStretchFactor = 3.

{
  "limbs": [
    { "juggler": 0, "type": "right hand" },
    { "juggler": 0, "type": "left hand" },
    { "juggler": 1, "type": "right hand" },
    { "juggler": 1, "type": "left hand" }
  ],
  "repetition": {
    "period": 6,

    "limbPermutation": [0, 1, 3, 2]
  },
  "throws": [
    { "time": 0, "duration": 6, "spins": 1, "from": 0, "to": 3},
    { "time": 3, "duration": 9, "spins": 1, "from": 1, "to": 0},

    { "time": 0, "duration": 9, "spins": 1, "from": 2, "to": 1},
    { "time": 2, "duration": 6, "spins": 1, "from": 3, "to": 2},
    { "time": 4, "duration": 6, "spins": 1, "from": 2, "to": 3}
 ], "timeStretchFactor": 2
}


Co Stuifbergen

Carl Hunt

unread,
Apr 6, 2022, 8:32:36 PM4/6/22
to juggling-interchange-format
Thanks, Co! That's great to know.

I thought I was getting somewhere with hand sitewap and JML by working out the single juggler version of 4-count fls (pattern=3423;hss=2231;) but couldn't apply it to two jugglers.
I've accepted I won't ever really understand sitewap. I'm going to work through the patterns I can with JIF and I'll describe the ones I cannot as best I can with words.
Here's an example of the videos I have in mind - https://youtu.be/EMcQb-n-y78
Reply all
Reply to author
Forward
0 new messages