package common;
use strict;
use POSIX qw(floor ceil);

sub arc($$$$ $$$){
    my ($x)             = shift; # center coordinate x
    my ($y)             = shift; # center coordinate y
    my ($start_angle)   = shift; # in degree
    my ($end_angle)     = shift; # in degree

    my ($radius)        = shift; # in micron
    my ($polygon_count) = shift; # default 12;
    my ($direction)     = shift; # -1 counter clockwise, 1 clockwise

    if ($polygon_count eq '') { $polygon_count = 12;}           # 多角形の数の既定値

    my (@PTR);
 #    if ($end_angle < $start_angle ) {
 #        my $t = $end_angle;                                     # 必ず end_angle > start_angle になる
 #        $end_angle = $start_angle;                              # ように入替える
 #        $start_angle = $t;
 #        $direction = - 1 * $direction; # toggle in this case      # direction をそれに合せて反転
 #    }
    if ($end_angle == $start_angle) { $start_angle = 0; $end_angle = 360;}
                                                                # 開始と終了が同じ時には 0 .. 360 

    my ($step)          =                                       # 一つ毎の角度を求める
    ($end_angle - $start_angle)/$polygon_count;
    my ($count)         = ceil(($end_angle - $start_angle)/$step);
                                                                # 頂点数を求める
#    print __LINE__. ' ' . $count, "\n";
    foreach my $i (0 .. $count ){                               # 頂点数だけ繰返し
        my $radian = ($start_angle + $i * $step) * 3.1415926535/180;
        push(@PTR, [                                            # 座標の組を書き連ねて行く
             $x + $radius * cos($radian),
             $y + $radius * sin($radian)]);
    }
    if ($direction < 0 ){ @PTR = reverse @PTR ;}                # 指定のある時は逆順にする
    my @COORDS;
    foreach my $i (0 .. $count){                                # 書き連ねた組をバラにして詰直し
        push(@COORDS, ($PTR[$i]->[0],
                       $PTR[$i]->[1] ) );
    }
    return @COORDS
}
sub rotate ($$$) {
    my ($x)     = shift;
    my ($y)     = shift;
    my ($angle) = shift;
    
#
#    X     cos(theta)  -sin(theta)   x
#       = 
#    Y     sin(theta)   cos(theta)   y
#
    my ($theta) = $angle/180 * 3.1415192;

    ## https://mathwords.net/heimenkaiten

    my ($X) = $x * cos($theta) + $y * - sin($theta);
    my ($Y) = $x * sin($theta) + $y *   cos($theta);
    return ($X, $Y);
}

# 二点を通る直線の方程式 の 三つの値 
#              y2 - y1
#   y - y1 = ---------- (x - x1)
#              x2 - x1
#  y を求めたい時の形
#        y = ax - b;
#
#              y2 - y1
#         a = ---------
#              x2 - x1

#              y2 - y1
#         b = --------- * (- x1) + y1
#              x2 - x1

# --------------------------------------
#              x2 - x1
#  (x - x1) = ---------- (y - y1)
##             y2 - y1  
#
#  x を求めたい時の形
#         x =  cy - d;
#
#              x2 - x1
#         c = ----------
#              y2 - y1  
#
#              x2 - x1
#         d  = --------- * ( -y1) + x1
#              y2 - y1  
#
#
sub cross_point_y ($$$$ $) {
    my $x1 = shift;
    my $y1 = shift;
    my $x2 = shift;
    my $y2 = shift;

    my $x = shift;
    my $y;

    if    ($x1 == $x2 ) { $y = 0 }
    elsif ($y1 == $y2 ) { $y = $y1 }
    else {
    my $a = ( $y2 - $y1 ) / ( $x2 - $x1);
    my $b = - $a * $x1 + $y1;

    my $c = ( $x2 - $x1 ) / ( $y2 - $y1);
    my $d = - $c * $y1 + $x1;

    $y = $a * $x + $b;
    }
    return $y;
}
sub box($$$) {
    my $size     = shift;
    my $layer    = shift;
    my $gds2File = shift;
    my $name = sprintf "box-%03d", $size;
    $gds2File -> printBgnstr (-name => $name);
    $gds2File -> printBoundary (
	-xy => [ -$size/2, -$size/2, $size/2, -$size/2,
		  $size/2,  $size/2, -$size/2, $size/2],
        -layer => $layer);
    $gds2File -> printEndstr ();
    return $name;
}
sub cross($$$$$$) {
    my $x = shift;
    my $y = shift;
    my $l   = shift;
    my $L10 = shift;
    my $mark_layer = shift;
    my $gds2File = shift;

    my $name = sprintf "Cross-L%05.2f", $l;
    $gds2File -> printBgnstr(-name => $name);    
    $gds2File -> printPath (
	    -xy =>[ $x - $l/2,  $y     ,
		    $x + $l/2,  $y      ],
	    -layer => $mark_layer);
    $gds2File -> printPath (
	    -xy =>[ $x,  $y - $l/2    ,
		    $x,  $y + $l/2     ],
	    -layer => $mark_layer);

    $gds2File -> printEndstr();
    return $name;
}

1;
