La question traitée ici concerne le mapping de données dans un espace cyclique. Le traitement d'angle est le premier qui me vient en tête.

javascript (p5.js)

manipulation:

  • right-click & drag to modify mapping angle
  • left-click & drag to modify mapping range

code:

functions (js)

First important method is cyclic_bound. Its role is to remap any value in the given range [from_in,from_out]. It's a modulo in both directions.

function cyclic_bound( value, from_in, from_out ) {
  if ( value >= from_in && value <= from_out ) { 
    return value;
  }
  var d = from_out - from_in;
  while( value < from_in ) {
    value += d;
  }
  while( value > from_out ) {
    value -= d;
  }
  return value;
}

cyclic_bound is applied on all entries of the mapping function.

function cyclic_map( value, from_in, from_out, to_in, to_out ) {
   
   var half = ( from_out - from_in ) * 0.5;
   var bvalue = cyclic_bound( value, from_in, from_out );
   
   var bin = cyclic_bound( to_in, from_in, from_out );
   var bout = cyclic_bound( to_out, from_in, from_out );
   var bmid = cyclic_bound( to_in + ( to_out - to_in ) * 0.5, from_in, from_out );
   
   var pc = cyclic_bound( ( bvalue - bmid ) / half, -1, 1 );
   var brange = cyclic_bound( half - ( bmid - bin ), -half, half );
   if ( pc >= 0 ) {
     return cyclic_bound( bout + (brange * pc), from_in, from_out );
   }
   return cyclic_bound( bin + (brange * pc), from_in, from_out );
   
}

remapping angles

base

 |--------*-----------------*-----------*--------------*--------|
 0        a                 b           c              d       2PI
 

l´idée est d´écarter 2 valeurs consécutives, b et c par ex, et de rediffuser les 2 autres, a et d, de manière proportionnelle

pour ce faire > calcul du point médian x

 |--------*-----------------*-----!-----*--------------*--------|
 0        a                 b     x     c              d       2PI

distance bx = (c-b) x = b + bx/2

le remap spécifie les nouvelles valeurs de b et de c

 |--------*--------<--------*-----!-----*-------->------*--------|
 0        a        b´       b     x     c        c´     d       2PI

distance b´x = (c´-b´) x = b + bx/2

on a donc perdu (b´x - bx) radians

  |----*---------|----*---------|----*---------|
-2PI   a´        0    a        2PI   a´´      4PI

ce qu´il ne faut pas oublier: l´espace est cyclique > a´ ~ a ~ a´´

on peut descendre en négatif et passer 2PI sans que ça pose de réel problème

 |---!--------*-----------*-----*----------*-----|---!--------*
 0   x´       a           b     c          d    2PI  x        a´
     3        11          22    27         37   42   45       53

l´angle entre d et a est à plusieurs positions simultanément pour son calcul: ( d + a ) / 2 - ( 37 + 11 ) -> 48!!!!, divisé par 2, on arrive à 24, donc pas du tout où il faut! il faut ajouter 42 à a => 53, et là: (37+57)/2, 90/2 => 45 paf! si a < d,

   a += 2PI

center = (d+a)/2

remap method()

dans le remap, je demande un recalcul de b dans les bornes d > a vers d-5, a + 5

   a, in, out, in_to, out_to
   b, 11, 37,  16,    32
 |-----------*--->--*---*---*----------*---<--*-----|
 0           |      |   |   |          |      |    2PI
             a      |   c   b          |      d    
             11     |   19  22         |      37
 0                  |´  |   |          |
                    |   \   |          |
                   a´    c´ b´         d´
                  16  20.9  22.8       32

? b´

distance_b distance_init distance_new percent_b out_b si b < d:

   distance_b = b - a => 11
   distance_init = d - a => 26
   distance_new = d´ - a´ => 16
   percent_b = distance_b / distance_init = > 0.423076923
   out_b = a´ + percent_b * distance_new (6.769230769) => 22.769230769

return out_b

pour c´ si c < d:

   distance_c = b - a => 8
   distance_init = d - a => 26
   distance_new = d´ - a´ => 16
   percent_b = distance_c / distance_init = > 0.307692308
   out_b = a´ + percent_b * distance_new (4.923076923) => 20.923076923

return out_b

le process semble ok pour les angles compris entre a et d

online identity ∋ [ social ∋ [mastodon♥, twitter®, facebook®, diaspora, linkedin®] ∥ repos ∋ [github®, gitlab♥, bitbucket®, sourceforge] ∥ media ∋ [itch.io®, vimeo®, peertube♥, twitch.tv®, tumblr®] ∥ communities ∋ [godotengine♥, openprocessing, stackoverflow, threejs]]