FUNCTION enclose_cregion_in_pregion

(* SCHEMA Ap242_managed_model_based_3d_engineering_mim_LF; *)
FUNCTION enclose_cregion_in_pregion(crgn   : cartesian_complex_number_region;
                                    centre : complex_number_literal)
                                   : polar_complex_number_region;
  -- Find equivalent direction in range -PI < a <= PI.
  FUNCTION angle(a : REAL) : REAL;
    REPEAT WHILE a > PI;    a := a - 2.0*PI;  END_REPEAT;
    REPEAT WHILE a <= -PI;  a := a + 2.0*PI;  END_REPEAT;
    RETURN (a);
  END_FUNCTION;
  -- Determine whether a real is strictly within a real interval
  FUNCTION strictly_in(z    : REAL;
                       zitv : real_interval) : LOGICAL;
    RETURN ((NOT min_exists(zitv) OR (z > real_min(zitv))) AND
      (NOT max_exists(zitv) OR (z < real_max(zitv))));
  END_FUNCTION;
  -- Include direction in minmax collection
  PROCEDURE angle_minmax(    ab, a            : REAL;
                             a_in             : BOOLEAN;
                         VAR amin, amax       : REAL;
                         VAR amin_in, amax_in : BOOLEAN);
    a := angle(a - ab);
    IF amin = a THEN  amin_in := amin_in OR a_in;  END_IF;
    IF amin > a THEN  amin := a;  amin_in := a_in;  END_IF;
    IF amax = a THEN  amax_in := amax_in OR a_in;  END_IF;
    IF amax < a THEN  amax := a;  amax_in := a_in;  END_IF;
  END_PROCEDURE;
  -- Include distance in max collection
  PROCEDURE range_max(    r       : REAL;
                          incl    : BOOLEAN;
                      VAR rmax    : REAL;
                      VAR rmax_in : BOOLEAN);
    IF rmax = r THEN  rmax_in := rmax_in OR incl;   END_IF;
    IF rmax < r THEN  rmax := r;  rmax_in := incl;  END_IF;
  END_PROCEDURE;
  -- Include distance in min collection
  PROCEDURE range_min(    r       : REAL;
                          incl    : BOOLEAN;
                      VAR rmin    : REAL;
                      VAR rmin_in : BOOLEAN);
    IF rmin = r THEN  rmin_in := rmin_in OR incl;  END_IF;
    IF (rmin < 0.0) OR (rmin > r) THEN  rmin := r;  rmin_in := incl;  END_IF;
  END_PROCEDURE;
  LOCAL
    xitv, yitv : real_interval;
    is_xmin, is_xmax, is_ymin, is_ymax : BOOLEAN;
    xmin, xmax, ymin, ymax, xc, yc : REAL := 0.0;
    xmin_in, xmax_in, ymin_in, ymax_in : BOOLEAN := FALSE;
    rmin, rmax : REAL := -1.0;
    amin : REAL := 4.0;
    amax : REAL := -4.0;
    rmax_exists, outside : BOOLEAN := TRUE;
    rmin_in, rmax_in, amin_in, amax_in : BOOLEAN := FALSE;
    ab, a, r : REAL := 0.0;
    incl : BOOLEAN;
    ritv : real_interval;
    aitv : finite_real_interval;
    minclo, maxclo : open_closed := open;
  END_LOCAL;
  IF NOT EXISTS (crgn) OR NOT EXISTS (centre) THEN  RETURN (?);  END_IF;
  -- Extract elementary input information
  xitv := crgn.real_constraint;
  yitv := crgn.imag_constraint;
  xc := centre.real_part;
  yc := centre.imag_part;
  is_xmin := min_exists(xitv);
  is_xmax := max_exists(xitv);
  is_ymin := min_exists(yitv);
  is_ymax := max_exists(yitv);
  IF is_xmin THEN  xmin := real_min(xitv);  xmin_in := min_included(xitv);  END_IF;
  IF is_xmax THEN  xmax := real_max(xitv);  xmax_in := max_included(xitv);  END_IF;
  IF is_ymin THEN  ymin := real_min(yitv);  ymin_in := min_included(yitv);  END_IF;
  IF is_ymax THEN  ymax := real_max(yitv);  ymax_in := max_included(yitv);  END_IF;
  rmax_exists := is_xmin AND is_xmax AND is_ymin AND is_ymax;
  -- Identify base direction with respect to which all relevant directions lie
  -- within +/- 0.5*PI, or that the centre lies properly inside crgn.
  IF       is_xmin AND (xc <= xmin)  THEN  ab := 0.0;
  ELSE IF  is_ymin AND (yc <= ymin)  THEN  ab := 0.5*PI;
  ELSE IF  is_ymax AND (yc >= ymax)  THEN  ab := -0.5*PI;
  ELSE IF  is_xmax AND (xc >= xmax)  THEN  ab := PI;
  ELSE                                     outside := FALSE;
  END_IF;  END_IF;  END_IF;  END_IF;
  IF NOT outside AND NOT rmax_exists THEN
    RETURN (?);  -- No enclosing polar region exists (requires whole plane)
  END_IF;
  -- Identify any closest point on a side but not a corner.
  IF       is_xmin AND (xc <= xmin) AND strictly_in(yc,yitv) THEN
    rmin := xmin - xc;  rmin_in := xmin_in;
  ELSE IF  is_ymin AND (yc <= ymin) AND strictly_in(xc,xitv) THEN
    rmin := ymin - yc;  rmin_in := ymin_in;
  ELSE IF  is_ymax AND (yc >= ymax) AND strictly_in(xc,xitv) THEN
    rmin := yc - ymax;  rmin_in := ymax_in;
  ELSE IF  is_xmax AND (xc >= xmax) AND strictly_in(yc,yitv) THEN
    rmin := xc - xmax;  rmin_in := xmax_in;
  END_IF;  END_IF;  END_IF;  END_IF;
  IF is_xmin THEN
    IF is_ymin THEN  -- Consider lower left corner
      r := SQRT((xmin-xc)**2 + (ymin-yc)**2);
      incl := xmin_in AND ymin_in;
      IF rmax_exists THEN  range_max(r,incl,rmax,rmax_in);  END_IF;
      IF outside THEN
        IF r > 0.0 THEN
          range_min(r,incl,rmin,rmin_in);
          a := angle(atan2(ymin-yc,xmin-xc) - ab);
          IF xc = xmin THEN  incl := xmin_in;  END_IF;
          IF yc = ymin THEN  incl := ymin_in;  END_IF;
          angle_minmax(ab,a,incl,amin,amax,amin_in,amax_in);
        ELSE  -- Centre at lower left corner
          rmin := 0.0;                rmin_in := xmin_in AND ymin_in;
          amin := angle(0.0-ab);      amin_in := ymin_in;
          amax := angle(0.5*PI-ab);   amax_in := xmin_in;
        END_IF;
      END_IF;
    ELSE IF xc <= xmin THEN  -- Consider points near (xmin, -infinity)
      angle_minmax(ab,-0.5*PI,(xc=xmin) AND xmin_in,amin,amax,amin_in,amax_in);
    END_IF;  END_IF;
    IF NOT is_ymax AND (xc <= xmin) THEN  -- Consider points near (xmin, +infinity)
      angle_minmax(ab,0.5*PI,(xc=xmin) AND xmin_in,amin,amax,amin_in,amax_in);
    END_IF;
  END_IF;
  IF is_ymin THEN
    IF is_xmax THEN  -- Consider lower right corner
      r := SQRT((xmax-xc)**2 + (ymin-yc)**2);
      incl := xmax_in AND ymin_in;
      IF rmax_exists THEN  range_max(r,incl,rmax,rmax_in);  END_IF;
      IF outside THEN
        IF r > 0.0 THEN
          range_min(r,incl,rmin,rmin_in);
          a := angle(atan2(ymin-yc,xmax-xc) - ab);
          IF xc = xmax THEN  incl := xmax_in;  END_IF;
          IF yc = ymin THEN  incl := ymin_in;  END_IF;
          angle_minmax(ab,a,incl,amin,amax,amin_in,amax_in);
        ELSE  -- Centre at lower right corner
          rmin := 0.0;                rmin_in := xmax_in AND ymin_in;
          amin := angle(0.5*PI-ab);   amin_in := ymin_in;
          amax := angle(PI-ab);       amax_in := xmax_in;
        END_IF;
      END_IF;
    ELSE IF yc <= ymin THEN  -- Consider points near (+infinity, ymin)
      angle_minmax(ab,0.0,(yc=ymin) AND ymin_in,amin,amax,amin_in,amax_in);
    END_IF;  END_IF;
    IF NOT is_xmin AND (yc <= ymin) THEN  -- Consider points near (-infinity, ymin)
      angle_minmax(ab,PI,(yc=ymin) AND ymin_in,amin,amax,amin_in,amax_in);
    END_IF;
  END_IF;
  IF is_xmax THEN
    IF is_ymax THEN  -- Consider upper right corner
      r := SQRT((xmax-xc)**2 + (ymax-yc)**2);
      incl := xmax_in AND ymax_in;
      IF rmax_exists THEN  range_max(r,incl,rmax,rmax_in);  END_IF;
      IF outside THEN
        IF r > 0.0 THEN
          range_min(r,incl,rmin,rmin_in);
          a := angle(atan2(ymax-yc,xmax-xc) - ab);
          IF xc = xmax THEN  incl := xmax_in;  END_IF;
          IF yc = ymax THEN  incl := ymax_in;  END_IF;
          angle_minmax(ab,a,incl,amin,amax,amin_in,amax_in);
        ELSE  -- Centre at lower left corner
          rmin := 0.0;                rmin_in := xmax_in AND ymax_in;
          amin := angle(-PI-ab);      amin_in := ymax_in;
          amax := angle(-0.5*PI-ab);  amax_in := xmax_in;
        END_IF;
      END_IF;
    ELSE IF xc >= xmax THEN  -- Consider points near (xmax, +infinity)
      angle_minmax(ab,0.5*PI,(xc=xmax) AND xmax_in,amin,amax,amin_in,amax_in);
    END_IF;  END_IF;
    IF NOT is_ymin AND (xc >= xmax) THEN  -- Consider points near (xmax, -infinity)
      angle_minmax(ab,-0.5*PI,(xc=xmax) AND xmax_in,amin,amax,amin_in,amax_in);
    END_IF;
  END_IF;
  IF is_ymax THEN
    IF is_xmin THEN  -- Consider upper left corner
      r := SQRT((xmin-xc)**2 + (ymax-yc)**2);
      incl := xmin_in AND ymax_in;
      IF rmax_exists THEN  range_max(r,incl,rmax,rmax_in);  END_IF;
      IF outside THEN
        IF r > 0.0 THEN
          range_min(r,incl,rmin,rmin_in);
          a := angle(atan2(ymax-yc,xmin-xc) - ab);
          IF xc = xmin THEN  incl := xmin_in;  END_IF;
          IF yc = ymax THEN  incl := ymax_in;  END_IF;
          angle_minmax(ab,a,incl,amin,amax,amin_in,amax_in);
        ELSE  -- Centre at lower right corner
          rmin := 0.0;                rmin_in := xmin_in AND ymax_in;
          amin := angle(0.5*PI-ab);   amin_in := ymax_in;
          amax := angle(PI-ab);       amax_in := xmin_in;
        END_IF;
      END_IF;
    ELSE IF yc >= ymax THEN  -- Consider points near (-infinity, ymax)
      angle_minmax(ab,PI,(yc=ymax) AND ymax_in,amin,amax,amin_in,amax_in);
    END_IF;  END_IF;
    IF NOT is_xmax AND (yc >= ymax) THEN  -- Consider points near (+infinity, ymax)
      angle_minmax(ab,0.0,(yc=ymax) AND ymax_in,amin,amax,amin_in,amax_in);
    END_IF;
  END_IF;
  IF outside THEN  -- Change direction origin from ab back to zero
    amin := angle(amin+ab);
    IF amin = PI THEN  amin := -PI;  END_IF;
    amax := angle(amax+ab);
    IF amax <= amin THEN  amax := amax + 2.0*PI;  END_IF;
  ELSE
    amin := -PI;  amin_in := FALSE;
    amax := PI;   amax_in := FALSE;
  END_IF;
  IF amin_in THEN  minclo := closed;  END_IF;
  IF amax_in THEN  maxclo := closed;  END_IF;
  aitv := make_finite_real_interval(amin,minclo,amax,maxclo);
  minclo := open;
  IF rmin_in THEN  minclo := closed;  END_IF;
  IF rmax_exists THEN
    maxclo := open;
    IF rmax_in THEN  maxclo := closed;  END_IF;
    ritv := make_finite_real_interval(rmin,minclo,rmax,maxclo);
  ELSE
    ritv := make_real_interval_from_min(rmin,minclo);
  END_IF;
  RETURN (make_polar_complex_number_region(centre,ritv,aitv));
END_FUNCTION;  -- enclose_cregion_in_pregion

Referenced By

Defintion enclose_cregion_in_pregion is references by the following definitions:
DefinitionType
 compatible_complex_number_regions FUNCTION
 subspace_of FUNCTION


[Top Level Definitions] [Exit]

Generated by STEP Tools® EXPRESS to HTML Converter
2012-03-27T17:20:10-04:00