sdr 0.7

net.cscott.sdr.calls
Class DancerPath

java.lang.Object
  extended by net.cscott.sdr.calls.DancerPath

public class DancerPath
extends Object

A DancerPath is the result of evaluating a call for a specific dancer in a formation. Unlike a Prim, a DancerPath is an absolute motion, and includes computed information about flow, roll, sweep, and timing.

The flow information we collect is based on Lynette Bellini's Rules of Flow, along with Dave Wilson's theories about dancer kinematics; to wit: certain "bad flow" motions actually work if there is hand contact between certain dancers, as it lets them push off of one another.

Version:
$Id: DancerPath.java,v 1.3 2007-03-07 22:05:29 cananian Exp $
Author:
C. Scott Ananian
Tests:
Simple pass thru movement:
js> importPackage(net.cscott.sdr.util);
js> dp = new DancerPath(Position.getGrid(-1,-3,"n"),
  >                     Position.getGrid(-1,-1,"n"),
  >                     Fraction.valueOf(2), null);
DancerPath[from=-1,-3,n,to=-1,-1,n,time=2,pointOfRotation=<null>]
js> dp.tangentStart()
0,1
js> dp.tangentFinish()
0,1
js> dp.bezierPath()
[-1,-3, -1,-2 1/3, -1,-1 2/3, -1,-1]
js> dp.bezierDirection()
[0,2, 0,2, 0,2]
js> dp.isStandStill()
false
js> dp.scaleTime(Fraction.valueOf(2));
DancerPath[from=-1,-3,n,to=-1,-1,n,time=4,pointOfRotation=<null>]
js> dp.scaleTime(Fraction.valueOf(2)).bezierPath()
[-1,-3, -1,-1 2/3, -1,-2 1/3, -1,-1]
js> dp.mirror(false)
DancerPath[from=1,-3,n,to=1,-1,n,time=2,pointOfRotation=<null>]
js> dp.mirror(true)
DancerPath[from=1,-3,n,[PASS_LEFT],to=1,-1,n,[PASS_LEFT],time=2,pointOfRotation=<null>]
Half-sashay, twice (boy's part):
js> importPackage(net.cscott.sdr.util);
js> dp1 = new DancerPath(Position.getGrid(-1,-3,"n"),
  >                      Position.getGrid( 0,-4,"n"),
  >                      Fraction.valueOf(2), null,
  >                      DancerPath.Flag.SASHAY_FINISH);
DancerPath[from=-1,-3,n,to=0,-4,n,time=2,pointOfRotation=<null>,flags=[SASHAY_FINISH]]
js> dp1.tangentStart()
0,-1
js> dp1.tangentFinish()
1,0
js> dp1.bezierPath()
[-1,-3, -1,-3 2/3, -2/3,-4, 0,-4]
js> dp1.bezierDirection()
[0,1, 0,1]
js> dp1.isStandStill()
false
js> dp2 = new DancerPath(Position.getGrid(0, -4, "n"),
  >                      Position.getGrid(1, -3, "n"),
  >                      Fraction.valueOf(2), null,
  >                      DancerPath.Flag.SASHAY_START);
DancerPath[from=0,-4,n,to=1,-3,n,time=2,pointOfRotation=<null>,flags=[SASHAY_START]]
js> dp2.tangentStart()
1,0
js> dp2.tangentFinish()
0,1
js> dp2.bezierPath()
[0,-4, 2/3,-4, 1,-3 2/3, 1,-3]
js> dp2.bezierDirection()
[0,1, 0,1]
js> dp3 = new DancerPath(Position.getGrid(1, -3, "n"),
  >                      Position.getGrid(0, -2, "n"),
  >                      Fraction.valueOf(2), null,
  >                      DancerPath.Flag.SASHAY_FINISH);
DancerPath[from=1,-3,n,to=0,-2,n,time=2,pointOfRotation=<null>,flags=[SASHAY_FINISH]]
js> dp3.tangentStart()
0,1
js> dp3.tangentFinish()
-1,0
js> dp3.bezierPath()
[1,-3, 1,-2 1/3, 2/3,-2, 0,-2]
js> dp3.bezierDirection()
[0,1, 0,1]
js> dp4 = new DancerPath(Position.getGrid(0, -2, "n"),
  >                      Position.getGrid(-1, -3, "n"),
  >                      Fraction.valueOf(2), null,
  >                      DancerPath.Flag.SASHAY_START);
DancerPath[from=0,-2,n,to=-1,-3,n,time=2,pointOfRotation=<null>,flags=[SASHAY_START]]
js> dp4.tangentStart()
-1,0
js> dp4.tangentFinish()
0,-1
js> dp4.bezierPath()
[0,-2, -2/3,-2, -1,-2 1/3, -1,-3]
js> dp4.bezierDirection()
[0,1, 0,1]
An path with an unusual combination of sashay; facing direction is a linear transition between starting and ending direction.
js> importPackage(net.cscott.sdr.util);
js> dp = new DancerPath(Position.getGrid(0,0,"n"),
  >                     Position.getGrid(2,2,"e"),
  >                     Fraction.valueOf(2), null,
  >                     DancerPath.Flag.SASHAY_FINISH);
DancerPath[from=0,0,n,to=2,2,e,time=2,pointOfRotation=<null>,flags=[SASHAY_FINISH]]
js> dp.tangentStart()
0,1
js> dp.tangentFinish()
0,1
js> dp.bezierPath()
[0,0, 0,2/3, 2,1 1/3, 2,2]
js> dp.bezierDirection()
[0,1, 1,1, 1,0]
Make sure "stand still" paths work:
js> importPackage(net.cscott.sdr.util);
js> dp = new DancerPath(Position.getGrid(0,0,"n"),
  >                     Position.getGrid(0,0,"n"),
  >                     Fraction.valueOf(2), null);
DancerPath[from=0,0,n,to=0,0,n,time=2,pointOfRotation=<null>]
js> dp.tangentStart()
0,0
js> dp.tangentFinish()
0,0
js> dp.bezierPath()
[0,0, 0,0, 0,0, 0,0]
js> dp.bezierDirection()
[0,1, 0,1]
js> dp.bezierDirection().raise()
[0,1, 0,1, 0,1]
"Turn in place" paths turn in the 'minimum sweep' direction:
js> importPackage(net.cscott.sdr.util);
js> dp = new DancerPath(Position.getGrid(0,0,"ne"),
  >                     Position.getGrid(0,0,"nw"),
  >                     Fraction.valueOf(2), null);
DancerPath[from=0,0,ne,to=0,0,nw,time=2,pointOfRotation=<null>]
js> dp.tangentStart()
0,0
js> dp.tangentFinish()
0,0
js> dp.bezierPath()
[0,0, 0,0, 0,0, 0,0]
js> dp.bezierDirection()
[1,1, 0,1, -1,1]
js> dp = new DancerPath(Position.getGrid(0,0,"nw"),
  >                     Position.getGrid(0,0,"ne"),
  >                     Fraction.valueOf(2), null);
DancerPath[from=0,0,nw,to=0,0,ne,time=2,pointOfRotation=<null>]
js> dp.bezierDirection()
[-1,1, 0,1, 1,1]

Nested Class Summary
static class DancerPath.Flag
          Special movement properties of a DancerPath.
static class DancerPath.PointOfRotation
          In order to have a method of discussing the various motions encountered in square dance choreography, Lynette Bellini identified several points of rotation: A single dancer: the point of rotation is about the center of a single dancer, as in the call roll.
 
Field Summary
 Set<DancerPath.Flag> flags
          Additional properties of the path.
 Position from
          The rotations on the to and from positions should be exact.
 DancerPath.PointOfRotation pointOfRotation
          The point of rotation, for flow computations.
 Fraction time
          The time this motion should take.
 Position to
          The rotations on the to and from positions should be exact.
 
Constructor Summary
DancerPath(Position from, Position to, Fraction time, DancerPath.PointOfRotation pointOfRotation, Collection<DancerPath.Flag> flags)
           
DancerPath(Position from, Position to, Fraction time, DancerPath.PointOfRotation pointOfRotation, DancerPath.Flag... flags)
          Create an immutable DancerPath object.
 
Method Summary
 Point arcCenter()
          Return the approximate "center" of this arcing DancerPath, or null if this is a straight-line movement.
 DancerBezierPath bezier(Fraction startTime)
          Return a low-level DancerBezierPath for this DancerPath.
 Bezier.Bezier2D bezierDirection()
          Return a 2D bezier describing the dancer's facing direction.
 Bezier.Bezier2D bezierPath()
          Return a 2D bezier describing the dancer's complete path.
 boolean isStandStill()
          Return true iff this DancerPath corresponds to "standing still"; ie, it just syncs time and doesn't change any of a dancer's state.
static ExactRotation midPoint(ExactRotation a, ExactRotation b)
          Compute midpoint between given exact rotations, in minimum sweep direction.
 DancerPath mirror(boolean mirrorShoulderPass)
          Return a DancerPath like this one, except with mirrored position.
 DancerPath scaleTime(Fraction amount)
          Return an equivalent DancerPath that completes in an adjusted amount of time.
 Point tangentFinish()
          Return a unit vector describing the final tangent of the dancer's path, as a vector from (0,0) to the returned Point.
 Point tangentStart()
          Return a unit vector describing the initial tangent of the dancer's path, as a vector from (0,0) to the returned Point.
 String toString()
           
 DancerPath translate(Position from, Position to)
          Return a DancerPath like this one, except with the 'to' and 'from' positions warped to those given.
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 

Field Detail

from

public final Position from
The rotations on the to and from positions should be exact.


to

public final Position to
The rotations on the to and from positions should be exact.


time

public final Fraction time
The time this motion should take.


pointOfRotation

public final DancerPath.PointOfRotation pointOfRotation
The point of rotation, for flow computations. May be null for straight paths.


flags

public final Set<DancerPath.Flag> flags
Additional properties of the path.

Constructor Detail

DancerPath

public DancerPath(Position from,
                  Position to,
                  Fraction time,
                  DancerPath.PointOfRotation pointOfRotation,
                  DancerPath.Flag... flags)
Create an immutable DancerPath object.


DancerPath

public DancerPath(Position from,
                  Position to,
                  Fraction time,
                  DancerPath.PointOfRotation pointOfRotation,
                  Collection<DancerPath.Flag> flags)
Method Detail

arcCenter

public Point arcCenter()
Return the approximate "center" of this arcing DancerPath, or null if this is a straight-line movement.


tangentStart

public Point tangentStart()
Return a unit vector describing the initial tangent of the dancer's path, as a vector from (0,0) to the returned Point.


tangentFinish

public Point tangentFinish()
Return a unit vector describing the final tangent of the dancer's path, as a vector from (0,0) to the returned Point.


midPoint

public static ExactRotation midPoint(ExactRotation a,
                                     ExactRotation b)
Compute midpoint between given exact rotations, in minimum sweep direction. Breaks ties in CCW direction.

Tests:
js> DancerPath.midPoint(ExactRotation.ONE_EIGHTH, ExactRotation.SEVEN_EIGHTHS).normalize();
0
js> DancerPath.midPoint(ExactRotation.SEVEN_EIGHTHS, ExactRotation.ONE_EIGHTH).normalize();
0
js> DancerPath.midPoint(ExactRotation.ONE_EIGHTH, ExactRotation.FIVE_EIGHTHS).normalize();
7/8
js> DancerPath.midPoint(ExactRotation.FIVE_EIGHTHS, ExactRotation.ONE_EIGHTH).normalize();
7/8

bezier

public DancerBezierPath bezier(Fraction startTime)
Return a low-level DancerBezierPath for this DancerPath.


bezierPath

public Bezier.Bezier2D bezierPath()
Return a 2D bezier describing the dancer's complete path. The 't' parameter of the bezier should vary from 0 to 1 over time beats.


bezierDirection

public Bezier.Bezier2D bezierDirection()
Return a 2D bezier describing the dancer's facing direction. The 't' parameter of the bezier should vary from 0 to 1 over time beats. The ratio between the 'y' and 'x' components of the returned bezier gives the arctangent of the facing direction at time 't'.


isStandStill

public boolean isStandStill()
Return true iff this DancerPath corresponds to "standing still"; ie, it just syncs time and doesn't change any of a dancer's state.


scaleTime

public DancerPath scaleTime(Fraction amount)
Return an equivalent DancerPath that completes in an adjusted amount of time.


translate

public DancerPath translate(Position from,
                            Position to)
Return a DancerPath like this one, except with the 'to' and 'from' positions warped to those given.


mirror

public DancerPath mirror(boolean mirrorShoulderPass)
Return a DancerPath like this one, except with mirrored position.


toString

public String toString()
Overrides:
toString in class Object

sdr 0.7

Copyright © 2006-2009 C. Scott Ananian