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 "sleeving-by-square.pm")

sleeving-by-square.pm

#!/usr/pkg/bin/perl
package sleeving;
use GDS2;
use strict;
use POSIX qw(floor ceil);
    
require './text2gds.pm';
require './arc.pm';
require './rotate.pm';

# -----------------------------------------------------
#          generate structure circle
# -----------------------------------------------------
sub circle ($$$){
    my $radius = shift;
    my $polygon_count = shift;
    my $gds2File = shift;

    my $name = sprintf("circle-R%3.2f", $radius);
    
    $gds2File -> printBgnstr(-name => $name);
    $gds2File -> printBoundary (
	-xy => [arc::arc (0, 0, 0, 360, $radius, $polygon_count, ' ', 1)],
        -layer => 56 );
    $gds2File -> printEndstr();
    return $name;
}
# -----------------------------------------------------
#   calculate the coordinate on the circle from x or y
# ----------------------------------------------------
sub get_other($$) {
    my $x = shift;
    my $radius = shift;

       $x       *= 100;
       $radius  *= 100;

    my $y = sqrt(abs ($radius * $radius - $x * $x));
    return $y/100;
}
sub SqSIPHA {
    my ($args)     = @_;
    my ($size)     =  $args -> {-size}; # nm
    my ($angle)    =  $args -> {-angle};
    my ($layer)    =  $args -> {-layer};
    my ($gds2File) =  $args -> { -gds2File};

    my $name    = sprintf("SqSIPHA%dW%dnm", $angle, $size);
    my $W       = $size/1000;
    my $H       = $size/1000;

    $gds2File -> printBgnstr  (-name => $name);
    $gds2File -> printBoundary  (
       -xy=> [ 
            rotate::rotate(-$W/2, -$H/2, $angle),
            rotate::rotate( $W/2, -$H/2, $angle),
            rotate::rotate( $W/2,  $H/2, $angle),
            rotate::rotate(-$W/2,  $H/2, $angle)],
        -layer=> $layer
        );
    $gds2File -> printEndstr();
    return $name;
}
# -----------------------------------------------------
#    M A I N   S U B R O U T I N E
# -----------------------------------------------------
sub sleeving {
    my ($args)     = @_;
    my ($size)     =  $args -> {-size};
    my ($pitch)    =  $args -> {-pitch};    # segment length
    my ($gds2File) =  $args -> { -gds2File};
    my $structure_name = sprintf("sleeving-S%5.3f-P%3.3f", $size, $pitch);

    my $polygon = 
    inscribe_polygon ({
	-size  =>  $size - 0.15,
	-pitch =>  $pitch,
	-gds2File =>	$gds2File
		      });
    $gds2File -> printBgnstr( -name => $structure_name);
    my $radius_circle = $size/ 2 - 0.05;
    my $peripheral = $size * 3.14159265;
    my $count = int($peripheral/0.1) + 1;
    my @COORDS = arc::arc(0,0, 0, 360, $radius_circle,  $count, '', 1);
    my $angle_step = 360/$count;
    foreach my $i ( 0.. int($#COORDS/2)) {
	my $angle = $i * $angle_step;
	my $mod90 = $angle % 90;
	my $proxy = int(($mod90 + 2.5)/5) * 5;;
#	print __LINE__, $proxy,"\n";
	if ($proxy == 90 ) { $proxy = 0;}
	my $CP = sprintf("SqSIPHA%dW100nm", $proxy);
	$gds2File -> printSref( -name => $CP, -xy => [ $COORDS[$i * 2],  $COORDS[$i * 2 + 1]]);
    }
    $gds2File -> printSref( -name => $polygon, -xy => [0, 0]);
    $gds2File -> printEndstr();
    return $structure_name;
}

sub inscribe_polygon {
    my ($args)     = @_;
    my ($size)     =  $args -> {-size};
    my ($pitch)    =  $args -> {-pitch};    # segment length
    my ($gds2File) =  $args -> { -gds2File};

 my $structure_name = sprintf("inscribe_polygon-S%5.3f-P%3.3f", $size, $pitch);

# -------------------------------------
#       make reference cirlce
# -------------------------------------
my $polygon_count = int($size * 8);
if ($polygon_count < 72) { $polygon_count = 72;}
my $circle_name = circle( $size/2, $polygon_count, $gds2File);
# -------------------------------------


my $radius = $size /2;
my $ratio = 0.99; # 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 circle
    if ($radius * ( 1 - $ratio) > $pitch/2) {
    $ratio = ($radius - $pitch/2)/$radius ;
    printf("%04d ******** %3.2f  %3.2f\n", __LINE__,  $ratio, $pitch);
    }
  my $start_to_divide  = $radius * $ratio;
my $end_to_divide    = $radius * sqrt(2)/2;
    printf("%04d %3.2f  %3.2f\n", __LINE__,  $start_to_divide, $end_to_divide);

my $pre_count = floor($end_to_divide /$pitch);  # from whole size
my $quadrant_count =  $pre_count + 1;  # half after two extreme removed
  if ($quadrant_count <= 0 ) { $quadrant_count = 1;}
my $step =  $end_to_divide  / ($quadrant_count + 1) / 2;

    printf(
"%04d radius / pitch / pre count / quadrant count / step  / end to divide
      %3.2f /  %3.2f /       %4d /           %4d / %4.3f / %4.3f \n",
    __LINE__, $radius, $pitch, $pre_count, $quadrant_count, $step, $end_to_divide);

my @part_pointer;	#  for  0 .. 45 degree, on the circle line
my @rev_pointer;	#  for 45 .. 90 degree, on the circle 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 circle (in between)

# ------------------------------------------------------
#            from 0 to 45 degree
# ------------------------------------------------------

my $prev_y = 0;
my $last_y;
foreach my $i ( 0.. ($quadrant_count * 2 + 2)) {
    if ( ($i < ($quadrant_count * 2 + 1) * 0.9 ) &&
         ($i % 2 == 1 ) ) {next;} # every two step
    my $this_y =  $i * $step;  # increasing at 1st quadrant
    my $this_x = get_other($this_y, $radius);
#    print __LINE__ .' * ' . $index++,  ' ' , int ($step*100) / 100 , ' ' , $this_y, ' ' , $this_x. "\n";
    push(@part_pointer, [$this_x, $this_y]);
# ----------------------------------------
    push(@COORDS_PTR,   [$this_x, $prev_y]);
    push(@COORDS_PTR,   [$this_x, $this_y]);
    $prev_y = $this_y;
    $last_y = $this_y;
# ----------------------------------------
}
my $E = $last_y;
push(@COORDS_PTR,   [$last_y, $last_y]);

push(@pointer, @part_pointer);		# copy the first 0 .. 45 to whole

#push(@pointer, [$E, $E]);		# put the center point
#push(@COORDS_PTR, [$E, $E]);		# also add on actual coordinate.
#push(@COORDS_PTR, [$E - $step/2, $E - $step/2]);		# also add on actual coordinate.
# -------------------------------------------------------------------
#     from 45 to 90 degree,  copy 0 .. 45 data with reversed order
# -------------------------------------------------------------------
foreach my $i (reverse (0 .. $#part_pointer)) {
#    print __LINE__ .' * ' . $index++. "\n";
    push (@rev_pointer, [$part_pointer[$i] ->[$Y],
			 $part_pointer[$i] ->[$X]]);
# ----------------------------------------
#    push(@COORDS_PTR,   [$part_pointer[$i] ->[$Y],
#			 $part_pointer[$i] ->[$X]]);
# ----------------------------------------
}
my (@COPY);
@COPY = @COORDS_PTR;   

foreach my $i (reverse (0.. $#COPY)) {
    push(@COORDS_PTR, [$COPY[$i] ->[$Y], $COPY[$i] ->[$X]]);
#    print __LINE__. ' ' . $i, ' ', $COPY[$i] ->[0]. ' ' .  $COPY[$i] ->[1], "\n";
}

push(@pointer, @rev_pointer);	# copy the 45 .. 90 to whole (important to digit mark)

# ------------------------------

#       start real structure 
# ------------------------------

$gds2File -> printBgnstr(-name => $structure_name);

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 circle
    $gds2File -> printSref(
	-name => $circle_name,
	-xy => [0, 0]);
    text2gds::text_flat ( 0, -0.5, 53, 0.005, $structure_name, $gds2File);
$gds2File -> printEndstr();

return $structure_name;
}
1;
__END__
Last Update: Mon, 21 Feb 2022 10:13:01 GMT 1.66 2008/03/08