Perl で gdsii
実行環境
  Active Perl
     更新するには
ppm
  ppm
  DownLoad
  実行
Help
   perldoc GDS2
Examples
  basic-lines
  simple
  simple-sref
  aref
  circle
  circle-inverted
  sample-arc
  donut
  Inverted-Donuts
  Donuts_Combination
  Hello-World
  CP-array
  text2gds.pm
  rotate.pm
  rotate-rectangle
  arc.pm
  line-and-space-180
  triangle-array-nega
  sq_sleeve.pm
  TriangleGridStep
  triangle-array-nega-CP
  CirclesArray-SQ
  LargeCircles
  MA6-Alignment-mark.pm
  Alignment-Place
  Triangle-Grid
  Triangle-Grid-Wide
  ellipsis-polygons
  inscribe_polygon
  inscribe_polygon.pm
  inscribe_polygon-ellipsis.pm
  sleeving-by-square-sample
  sleeving-by-square.pm

Perl Perl/GDSII page
Download (as "inscribe_polygon-ellipsis.pm")

inscribe_polygon-ellipsis.pm

#!/usr/pkg/bin/perl
package inscribe;
use GDS2;
use strict;

require './text2gds.pm';
require './4110.ellipsis.pm';

# -----------------------------------------------------
#          generate structure ellipsis
# -----------------------------------------------------
sub ellipsis ($$$$){
    my $radiusX = shift;
    my $radiusY = shift;
    my $polygon_count = shift;
    my $gds2File = shift;

    my $name = sprintf("ellipsys-X%3.3f-Y%3.3f", $radiusX, $radiusY);
    
    $gds2File -> printBgnstr(-name => $name);
    $gds2File -> printBoundary (
	-xy => [ellipsis::ellipsis (0, 0, 0, 360, $radiusX, $radiusY, $polygon_count, ' ', 1)],
        -layer => 56 );
    $gds2File -> printEndstr();
    return $name;
}
# calculate the X coordinate of the point where the slant = 1;
sub equilibrium($$) {
    my $A = shift;
    my $B = shift;
    my $R = $A * $A / sqrt($A * $A + $B * $B);
    return $R;
    }
# -----------------------------------------------------
#   calculate the coordinate on the ellipsis from x or y
# ----------------------------------------------------
sub get_otherY($$$) {
    my $x = shift;
    my $radiusX = shift;
    my $radiusY = shift;

    my $y = $radiusY * sqrt( abs( 1  - $x * $x / ($radiusX * $radiusX)));
    return $y;
}
sub get_otherX($$$) {
    my $y = shift;
    my $radiusX = shift;
    my $radiusY = shift;

    my $x = $radiusX * sqrt( abs( 1  - $y * $y / ($radiusY * $radiusY)));
    return $x;
}

# -----------------------------------------------------
#    M A I N   S U B R O U T I N E
# -----------------------------------------------------
sub ellipsis_polygon($$$$$) {
  my $sizeX     = shift;    # size of ellipsis  (to inscribe)
  my $sizeY	= shift;
  my $pitch    = shift;    # segment length
  my $gds2File = shift;

  my $structure_name = sprintf("inscribe_polygon-X%03.3f-Y%03.3f-P%03.3f", $sizeX, $sizeY, $pitch);
  my $radiusX = $sizeX/2 + $pitch/2;
  my $radiusY = $sizeY/2 + $pitch/2;

# -------------------------------------
#       make reference ellipsis
# -------------------------------------
my $polygon_count = int($sizeX * 8);

if ($polygon_count < 72) { $polygon_count = 72;}
my $ellipsis_name = ellipsis( $sizeX/2, $sizeY/2, $polygon_count, $gds2File);
# -------------------------------------

my $ratio = 0.97; # start point ratio, set 1 makes the length of first segment equals to 0
# take care the case if the pitch is very small against the ellipsis
  if ($radiusX * ( 1 - $ratio) > $pitch/2) { $ratio = ($radiusX - $pitch/2)/$radiusX ; }
  
my $start_to_divide  = $radiusX * $ratio;
my $end_to_divide    = equilibrium($radiusX, $radiusY);

  my $step = $pitch;
  my $quadrant_count1 =  int(($start_to_divide - $end_to_divide)/$step);
  if ($quadrant_count1 == 0 ) { $quadrant_count1 = 1;}

#  printf("%04d pre count/partial count/step: %4d / %4d / %4.3f\n", __LINE__, $pre_count, $quadrant_count1, $step);

my @part_pointer;	#  for  0 .. 45 degree, on the ellipsis line
my @pointer;		#  for  0 .. 90 

my $index = 0;		# only for debug, not used for now

my $X = 0;		# constant Macro
my $Y = 1;		# ditto

my @COORDS_PTR;		# coordinate pointer, x1, y1, x2, y2, ... xn, yn
  			# add the coordinate inside of the ellipsis (in between)

  my $equillibrium = $end_to_divide;
# ------------------------------------------------------
#            from 0 to equillibrium
# ------------------------------------------------------
  my $step = $pitch;
  my $lasty;
  my $this_y;
#  print __LINE__ . ' ' . $quadrant_count1. "\n";
foreach my $i ( 0.. $quadrant_count1 - 1) {
#    print __LINE__ .' * ' . $index++. "\n";
    my $this_x = $start_to_divide - $i * $step;  # decreasing at 1st quadrant
       $this_y = get_otherY($this_x, $radiusX, $radiusY);
       $lasty = $this_y;
 if ($ != $quadrant_count1 - 1) {
    push(@pointer, [$this_x,         $this_y]);
# ----------------------------------------
    push(@COORDS_PTR,   [$this_x,         $this_y]);
    push(@COORDS_PTR,   [$this_x - $step, $this_y]);
# ----------------------------------------
 } else {

 }
}
#  print __LINE__. ' ' . $lasty  . "\n";
# -------------------------------------------------------------------
#     from equillibrium to 90 degree,
# -------------------------------------------------------------------

  $start_to_divide  = get_otherY($equillibrium, $radiusX, $radiusY);
  $end_to_divide  = $radiusY + $step / 2;
  
  my $quadrant_count2 =  int(($end_to_divide - $start_to_divide)/$step);

  if ($quadrant_count2 == 0 ) { $quadrant_count2 = 1;}

#  print __LINE__ . ' ' . $start_to_divide. "\n";
#  print __LINE__ . ' ' . $quadrant_count2. "\n";

#  pop(@pointer);
#  pop(@COORDS_PTR);
foreach my $i ( 0.. $quadrant_count2) {
#    print __LINE__ .' * ' . $index++. "\n";
    my $this_y = $start_to_divide + $i * $step;
    my $this_x = get_otherX($this_y, $radiusX, $radiusY);
    push(@pointer, [$this_x, $this_y]);
# ----------------------------------------
    if ($i != 0) {
    push(@COORDS_PTR,   [$this_x,         $this_y - $step]);
    } else {
    push(@COORDS_PTR,   [$this_x,         $lasty]);
    }
    if ($i != $quadrant_count2) {
    push(@COORDS_PTR,   [$this_x,         $this_y        ]);
    } else {
    push(@COORDS_PTR,   [$this_x,         $this_y - $step/2  ]);
    }
# ----------------------------------------
}
#  print __LINE__ . ' ' . $start_to_divide. "\n";
# ------------------------------
#       start real structure 
# ------------------------------

$gds2File -> printBgnstr(-name => $structure_name);
  if (1) {
for my $i ( 0..$#pointer){
    text2gds::text_flat( $pointer[$i] -> [$X], $pointer[$i] -> [$Y],
			15, $pitch/30, $i + 1, $gds2File); 
}
  }

my @COORDS;		# This will finally be the printBoundary coordinates.
# ------------------------------
#       pointer to vertex, one quadrant by one quadrant
# ------------------------------

for my $i ( 0..$#COORDS_PTR){
    push (@COORDS,         $COORDS_PTR[$i] -> [$X],
	                   $COORDS_PTR[$i] -> [$Y]);}
for my $i ( reverse 0..$#COORDS_PTR){
    push (@COORDS,       - $COORDS_PTR[$i] -> [$X],
	                   $COORDS_PTR[$i] -> [$Y]);}
for my $i ( 0..$#COORDS_PTR){
    push (@COORDS,       - $COORDS_PTR[$i] -> [$X],
	                 - $COORDS_PTR[$i] -> [$Y]);}
for my $i ( reverse 0..$#COORDS_PTR){
    push (@COORDS,         $COORDS_PTR[$i] -> [$X],
	                 - $COORDS_PTR[$i] -> [$Y]);}

$gds2File -> printBoundary  (-xy=> [@COORDS], -layer=> 0);

# place reference ellipsis
    $gds2File -> printSref(
	-name => $ellipsis_name,
	-xy => [0, 0]);
$gds2File -> printEndstr();
return $structure_name;
}
1;
__END__
Last Update: Mon, 21 Feb 2022 10:13:01 GMT 1.66 2008/03/08