Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

KramerPath

By: a guest on May 18th, 2013  |  syntax: Java  |  size: 3.61 KB  |  hits: 45  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. package com.axe.path;
  2.  
  3. import com.axe.core.Attribute;
  4. import com.axe.io.InputModel;
  5. import com.axe.io.OutputModel;
  6. import com.axe.math.Scalari;
  7.  
  8. public class KramerPath<T> implements Path<T>
  9. {
  10.        
  11.         public static final float DEFAULT_LOOSENESS = 0.0575f;
  12.        
  13.         protected Attribute<T>[] points;
  14.         protected Attribute<T> temp0;
  15.         protected Attribute<T> temp1;
  16.         protected int depth;
  17.         protected float looseness;
  18.         protected boolean loops;
  19.        
  20.         public KramerPath()
  21.         {
  22.         }
  23.        
  24.         public KramerPath( int depth, boolean loops, Attribute<T> ... points )
  25.         {
  26.                 this( depth, loops, DEFAULT_LOOSENESS, points );
  27.         }
  28.        
  29.         public KramerPath( int depth, boolean loops, float looseness, Attribute<T> ... points )
  30.         {
  31.                 this.depth = depth;
  32.                 this.loops = loops;
  33.                 this.looseness = looseness;
  34.                 this.points = points;
  35.                 this.temp0 = points[0].create();
  36.                 this.temp1 = points[0].create();
  37.         }
  38.        
  39.         @Override
  40.         public T set(Attribute<T> subject, float delta)
  41.         {
  42.                 final int n = points.length;
  43.                 final float a = delta * n;
  44.                 final int i = Scalari.clamp( (int)a, 0, n - 1 );
  45.                 float d = a - i;
  46.                
  47.                 // v0 and v5 are used to calculate the next v1 or v4, at the next level.
  48.                 T v0 = points[ getActualIndex( i - 2 ) ].get();
  49.                 T v1 = points[ getActualIndex( i - 1 ) ].get();
  50.                 T v2 = points[ getActualIndex( i ) ].get();
  51.                 T v3 = points[ getActualIndex( i + 1 ) ].get();
  52.                 T v4 = points[ getActualIndex( i + 2 ) ].get();
  53.                 T v5 = points[ getActualIndex( i + 3 ) ].get();
  54.                
  55.                 for (int k = 0; k < depth; k++)
  56.                 {
  57.                         // Get mid point
  58.                         T mid = getPoint( v1, v2, v3, v4 );
  59.                        
  60.                         // If the desired point is closer to v2...
  61.                         if (d < 0.5f)
  62.                         {
  63.                                 // shift all surrounding points one-level closer to v2
  64.                                 T newEnd = v1;
  65.                                 v5 = v4;
  66.                                 v4 = v3;
  67.                                 v3 = mid;
  68.                                 v1 = getPoint( v0, v1, v2, v3 );
  69.                                 v0 = newEnd;
  70.                                 // adjust d so it's between 0.0 an 1.0
  71.                                 d = d * 2.0f;
  72.                         }
  73.                         // else, the desired point is closer to v3...
  74.                         else
  75.                         {
  76.                                 // shift all surrounding points one-level closer to v3
  77.                                 T newEnd = v4;
  78.                                 v0 = v1;
  79.                                 v1 = v2;
  80.                                 v2 = mid;
  81.                                 v4 = getPoint( v2, v3, v4, v5 );
  82.                                 v5 = newEnd;
  83.                                 // adjust d so it's between 0.0 an 1.0
  84.                                 d = (d - 0.5f) * 2.0f;
  85.                         }
  86.                 }
  87.                
  88.                 // subject = (v3 - v2) * d + v2
  89.                 subject.interpolate( v2, v3, d );
  90.                
  91.                 return subject.get();
  92.         }
  93.        
  94.         public T getPoint( T v1, T v2, T v3, T v4 )
  95.         {
  96.                 // p = (0.5f + looseness) * (v2 + v3) - looseness * (v1 + v4)
  97.                
  98.                 temp0.set( v2 );
  99.                 temp0.add( v3, 1f );
  100.                 temp0.scale( 0.5f + looseness );
  101.                
  102.                 temp1.set( v1 );
  103.                 temp1.add( v4, 1f );
  104.                 temp0.add( temp1.get(), -looseness );
  105.                
  106.                 return temp0.clone();
  107.         }
  108.        
  109.         public int getActualIndex( int index )
  110.         {
  111.                 final int n = points.length;
  112.                
  113.                 return ( loops ? (index + n) % n : Scalari.clamp( index, 0, n - 1 ) );
  114.         }
  115.  
  116.         @Override
  117.         public int getAttributeCount()
  118.         {
  119.                 return points.length;
  120.         }
  121.  
  122.         @Override
  123.         public Attribute<T> getAttribute(int index)
  124.         {
  125.                 return points[ index ];
  126.         }
  127.  
  128.         @Override
  129.         public T get(int index)
  130.         {
  131.                 return points[ index ].get();
  132.         }
  133.        
  134.         public Attribute<T>[] points()
  135.         {
  136.                 return points;
  137.         }
  138.  
  139.         @Override
  140.         public void read( InputModel input )
  141.         {
  142.                 depth = input.readInt( "depth" );
  143.                 loops = input.readBoolean( "loops" );
  144.                 looseness = input.readFloat( "looseness" );
  145.                 points = input.readModelArray( "point", "point-type" );
  146.                 temp0 = points[0].create();
  147.                 temp1 = points[0].create();
  148.         }
  149.  
  150.         @Override
  151.         public void write( OutputModel output )
  152.         {
  153.                 output.write( "depth", depth );
  154.                 output.write( "loops", loops );
  155.                 output.write( "looseness", looseness );
  156.                 output.writeModelArray( "point", points, "point-type" );
  157.         }
  158.        
  159. }