*
;

               options nosource;
%macro trans (data,result,plotds,x,y,x_scale,y_scale,
                                     x_move ,y_move,
                                     angle, deg);

 /*Developed by Arnold Schick, University of Marburg/Germany
   December, 9, 1994

   Note: Plot dataset _PLOTDS_ includes dummy-corner-points
         which are X-,Y-Range from the input dataset and
         from the new transformated function.
   */

 options nosource nostimer nosymbolgen nonotes;

%if &data =  %then %do;
  %put ;
  %put macro-note: This macro is to call: ;
  %put ;
  %put macro-note:   trans(data,result,plotds,x,y,x_sc,y_sc,x_m,y_m,angle,deg);
  %put ;
  %put macro-note: and scales X-,Y-Values from input dataset DATA into;
  %put macro-note: wanted ranges of X, Y with possibility of moving;
  %put macro-note: in X-,Y-Directions and rotation about origin in X=0, Y=0. ;
  %put macro-note: The new values are written into dataset RESULT, ;
  %put macro-note: dataset _PLOTDS_ has data for plotting (proc GPLOT with;
  %put macro-note: plot option SKIPMISS) to show the effect.;
  %put macro-note: All transformations are on scope {x|0,1} and {y|1,0}.;
  %put ;
  %goto fin;
%end;

/*set default values*/
data _NULL_;
 k=symget('x_scale')/1.0;  if k=. then k=1; call symput('x_scale',k);
 k=symget('y_scale')/1.0;  if k=. then k=1; call symput('y_scale',k);
 k=symget('x_move')/1.0;   if k=. then k=0; call symput('x_move',k);
 k=symget('y_move')/1.0;   if k=. then k=0; call symput('y_move',k);
 k=symget('angle')/1.0;    if k=. then k=0; call symput('angle',k);
 if k ^= 0 then k=1; call symput('k',k);
run;

/*set default variablenames*/
%if &data = . %then %do;
      %let data    = _LAST_ ;
      %put macro-note: default input dataset is the _LAST_;
%end;
%if &result =  or &result = . %then %do;
      %let result = _NEW_ ;
      %put macro-note: default result dataset is _NEW_;
%end;
%if &plotds = or &plotds = . %then %do;
      %let plotds = _PLOTDS_ ;
      %put macro-note: default plotting data set is _PLOTDS_;
%end;
%if &x       =  or &x       = . %then %let x       = x;
%if &y       =  or &y       = . %then %let y       = y;
%if °= or ° =. or °=degrees or °=DEGREES
 or °=GRAD or °=grad %then %let deg     = deg;

proc means data=&data noprint min max;
  var &x &y ;
  output out=_minmax_ min=x_min y_min  max=x_max y_max ;
run;

data _NULL_;
  set _minmax_;
  call symput('x_min',x_min);  call symput('x_max',x_max);
  call symput('y_min',y_min);  call symput('y_max',y_max);
run;
options notes;
data &result;
  set &data;
  length default=8;
  &x = ((&x - &x_min)/(&x_max - &x_min))*&x_scale + &x_move;
  &y = ((&y - &y_min)/(&y_max - &y_min))*&y_scale + &y_move;
run;
options nonotes;
%if &k ^= 0 %then %do;
  data &result;
    set &result;
    keep &x &y;
    angle=∠
    if upcase("°") ^= upcase("DEG") then angle=angle*45/atan(1);
    r = sqrt(&x**2 + &y**2);
    if r ^= 0 then phi = arcos(&x/r); else phi=0;
    if &y < 0 then phi = 360 - phi * 45/atan(1);
              else phi = phi * 45/atan(1);
    phi + angle;
    phi = phi * atan(1)/45;
    &x = r*cos(phi);
    &y = r*sin(phi);
  run;
%end;
data &plotds;
  set &result;
run;
data _scope_ ;
  if &x_min = 0 then xd=0.01/(&x_max-&x_min); else xd=0;
  if &x_max = 0 then xr=0.01/(&x_max-&x_min); else xr=0;
  if &y_min = 0 then yd=0.01/(&y_max-&y_min); else yd=0;
  if &y_max = 0 then yr=0.01/(&y_max-&y_min); else yr=0;
  keep &x &y ;
  &x =.; &y =.; output;
  &x = &x_min - xd;  &y = &y_min - yd;   output;
  &x = &x_max + xr;  &y = &y_min - yd;   output;
  &x = &x_max + xr;  &y = &y_max + yr;   output;
  &x = &x_min - xd;  &y = &y_max + yr;   output;
  &x = &x_min - xd;  &y = &y_min - yd;   output;
  &x =.; &y =.; output;
run;

proc append base=&plotds data= _scope_ ; run;
proc append base=&plotds data= &data;    run;

proc means data=_scope_ noprint min max;
  var &x &y ;
  output out=_minmax_ min=x_min y_min  max=x_max y_max ;
run;

data _NULL_;
  set _minmax_;
  call symput('x_min',x_min);  call symput('x_max',x_max);
  call symput('y_min',y_min);  call symput('y_max',y_max);
run;

  data _scope_;
    set _scope_;
    keep &x &y;
    &x = ((&x - &x_min)/(&x_max - &x_min))*&x_scale + &x_move;
    &y = ((&y - &y_min)/(&y_max - &y_min))*&y_scale + &y_move;
    angle=∠
    if angle ^=0 then do;
      if upcase("°") ^= upcase("DEG") then angle=angle*45/atan(1);
      r = sqrt(&x**2 + &y**2);
      if r ^= 0 then phi = arcos(&x/r); else phi=0;
      if &y < 0 then phi = 360 - phi * 45/atan(1);
                else phi = phi * 45/atan(1);
      phi + angle;
      phi = phi * atan(1)/45;
      &x = r*cos(phi);
      &y = r*sin(phi);
     end;
  run;

proc append base=&plotds data= _scope_ ; run;

%fin : ;
options source stimer notes;
%mend trans;    options source;


/* Example:

data eins;
  do x=-5 to 5 by 0.25;
       if x ^=0 then y= cos(x) + 1/x**2;
        else y=.;
       output;
  end;
run;

*%trans(eins,zwei);   * scales into plane {x|0,1} and plane {y|0,1}  ;

*%trans(eins,zwei,,x,y, 10.75,5.2, -3.3,1.1, 10 );
 %trans(eins,zwei,,x,y,  1.9 ,0.7,     ,   , -60);

proc gplot data=_plotds_;
  symbol i=join ;
  plot y*x / skipmiss;
run; quit;
proc gplot data=zwei;
  plot y*x / skipmiss;
run; quit;
           */

*
;