jDSGI - Java2D DATA Step Graphics Interface
  Back - Next   [ 7 of 27 ]
image  
by Richard A. DeVenezia, Copyright 2004  HOME
/*
 * Richard A. DeVenezia
 * June 1, 2004
 *
 * jDSGI test 7
 */

data _null_;

 %*
  * geometric model based of formulas found at
  * http://mathworld.wolfram.com/Ellipse.html formula #25
  * (polar coordinate form where theta is measured from the
  * center of the ellipse)
  *
  *;

  if symexist('goutpath') then goutpath=symget('goutpath'); else goutpath=pathname('WORK');
  if symexist ('gsftype') then gsftype=symget('gsftype'); else gsftype='png';

  gsf = cats(goutPath,"\","test7");

  width  = 500;
  height = 500;

  %canvas (_g, width, height, 0ffffffx)

  * 0,0 -> ul  :  1,1 -> lr;

  cxf = 0.5;
  cyf = 0.5;

  * < 1, major is vertical
  * > 1, major is horizontal
  * =1, circle;

  whRatio = 1;

  cx = width  * cxf;
  cy = height * cyf;

  r1 = cx**2 + cy**2;                   * to ul;
  r2 = (width-cx)**2 + cy**2;           * to ur;
  r3 = cx**2 + (height-cy)**2;          * to ll;
  r4 = (width-cx)**2 + (height-cy)**2 ; * to lr;

  r1 = sqrt(r1);
  r2 = sqrt(r2);
  r3 = sqrt(r3);
  r4 = sqrt(r4);

  r = max (of r1-r4);

  _g.callVoidMethod ('setColor', 0000000x);

  if r = r1 then do;
    dy = -cy;
    dx = -cx;
  end;
  else
  if r = r2 then do;
    dy = -cy;
    dx = width - cx;
  end;
  else
  if r = r3 then do;
    dy = height - cy;
    dx = -cx;
  end;
  else
  if r = r4 then do;
    dy = height - cy;
    dx = width  - cx;
  end;

  ratio = -dy/dx;
  theta = atan (ratio);
  thetad = theta * 360 / 2 / constant('pi');

  e_sq = 1 - 1 / whRatio ** 2;

  k = ( 1 - e_sq * cos(theta)**2 ) / ( 1 - e_sq) ;

  n = 25;

  * m is best when odd;
  %let m = 7;

  array px[%eval(&m*2)];
  array py[%eval(&m*2)];

  m = &m;

  p1x = cos ( 0 );
  p1y = sin ( 0 );
  p2x = cos ( 2 / m * 2 * constant('PI') );
  p2y = sin ( 2 / m * 2 * constant('PI') );
  p3x = cos ( 1 / m * 2 * constant('PI') );
  p3y = sin ( 1 / m * 2 * constant('PI') );
  p4x = cos ( 3 / m * 2 * constant('PI') );
  p4y = sin ( 3 / m * 2 * constant('PI') );

  a1 = p2y - p1y;
  b1 = p1x - p2x;
  c1 = p2x * p1y - p1x * p2y;

  a2 = p4y - p3y;
  b2 = p3x - p4x;
  c2 = p4x * p3y - p3x * p4y;

  x = ( -c1 * b2 + c2 * b1 ) / ( a1 * b2 - a2 * b1 );
  y = ( -a1 * c2 + a2 * c1 ) / ( a1 * b2 - a2 * b1 );

  ri = sqrt (x**2 + y**2);

  initialRotate = - constant('PI') / 2;
  innerFactor = ri;
  innerRotate = constant('PI') / m;

  do i = 0 to n;

    f = i / n ;

    rhat = (1-f) * r;

    a_sq = rhat**2 * k;

    a = sqrt (a_sq);
    b = a / whRatio;

    ix = 0;

    do j = 1 to m;

      g = (j-1) / m;

      theta = 2 * constant('PI') * g + initialRotate;

      ix + 1;
      px[ix] = 1/ri * a * cos (theta) + cx;
      py[ix] = 1/ri *b * sin (theta) + cy;

      theta + innerRotate;

      ix + 1;
      px[ix] = 1/ri * innerFactor * a * cos (theta) + cx;
      py[ix] = 1/ri * innerFactor * b * sin (theta) + cy;

    end;

    initialRotate + 0.03;

    %setColorRGB ( 255
                    , 255 * (1-f)
                    , 255 * (1-f)
                    );

    %fillPolygon (px, py);

%macro x;
    _g.callVoidMethod ('drawOval', cx-a, cy-b, 2*a, 2*b);
    _g.callVoidMethod ('drawOval', cx-a*ri, cy-b*ri, 2*a*ri, 2*b*ri);

    _g.callVoidMethod ('drawLine', px[1],py[1], px[5], py[5]);
    _g.callVoidMethod ('drawLine', px[5],py[5], px[9], py[9]);
    _g.callVoidMethod ('drawLine', px[9],py[9], px[3], py[3]);
    _g.callVoidMethod ('drawLine', px[3],py[3], px[7], py[7]);
    _g.callVoidMethod ('drawLine', px[7],py[7], px[1], py[1]);
%mend;

  end;

  %canvas_saveAs (gsf, gsftype, savedAs);

  %canvas_delete();

  if savedAs ne '' then call system ("start " || savedAs);
run ;