#!/usr/bin/perl -w $| = 1; use strict; use JSON; use Data::Dumper; use Getopt::Std; use constant PI => 4 * atan2(1, 1); use constant MAX_WIND => 129; our($opt_h, $opt_p); getopts('hp:'); my $gen_h = $opt_h; my $pro = $opt_p // 0; #print "Pro: $pro\n"; my @SAILC = ( undef , [3,6], [4], [3,4,6], [2,5], [2,3,5,6], [2,4,5], [2,3,4,5,6] ); my $o; { local $/= undef; $o = decode_json(<>); } my $polars = $o->{scriptData}->{polar}; my $tws = $polars->{tws}; my $twa = $polars->{twa}; my $twaMax = $polars->{foil}->{twaMax}; my $twaMin = $polars->{foil}->{twaMin}; my $twaMerge = $polars->{foil}->{twaMerge}; my $twsMax = $polars->{foil}->{twsMax}; my $twsMin = $polars->{foil}->{twsMin}; my $twsMerge = $polars->{foil}->{twsMerge}; my $foilSpeedRatio = $polars->{foil}->{speedRatio}; my $hullSpeedRatio = $polars->{hull}->{speedRatio}; my $sails = $polars->{sail}; sub max ($$) { $_[$_[0] < $_[1]] }; sub min ($$) { $_[$_[0] > $_[1]] } sub pro_coeff($$) { my ($tws, $twa) = @_; return $hullSpeedRatio; my $k1 = min(1, max(0, ($twa - $twaMin + $twaMerge) / $twaMerge)) * min(1, max(0, (-$twa + $twaMax + $twaMerge) / $twaMerge)); my $k2 = min(1, max(0, ($tws - $twsMin + $twsMerge) / $twsMerge)) * min(1, max(0, (-$tws + $twsMax + $twsMerge) / $twsMerge)); return (1 + $k1 * $k2 * ($foilSpeedRatio - 1)) * $hullSpeedRatio; } my @SAILDATA; for my $twa (0..180) { for my $tws (0..130) { for my $sail (0..7) { $SAILDATA[$twa][$tws][$sail] = 0; } } } sub interpolate_sail_wind($) { my $sail = shift; for my $a (0..$#$twa) { my $hiw = 0; for my $wind (0..MAX_WIND) { if (defined($tws->[$hiw+1]) && $wind/1.852 >= $tws->[$hiw]) { $hiw ++; } my $v1 = $sails->[$sail]->{speed}->[$a][$hiw-1]; my $v2 = $sails->[$sail]->{speed}->[$a][$hiw]; # if ($pro == 7) { # my $k = pro_coeff($wind/1.852,$twa->[$a]); # $v1 *= $k; # $v2 *= $k; # } my $wind1 = $tws->[$hiw-1]; my $wind2 = $tws->[$hiw]; if (defined($tws->[$hiw])) { $SAILDATA[$twa->[$a]][$wind][$sail] = $v1+($v2-$v1)*($wind/1.852-$wind1)/($wind2-$wind1); } else { $SAILDATA[$twa->[$a]][$wind][$sail] = $v2; } } } } sub interpolate_sail($) { my $sail = shift; for my $wind(0..MAX_WIND) { for my $i (0..$#$twa-1) { my $lowa = $twa->[$i]; my $higha = $twa->[$i+1]; # print "$higha $lowa $wind $sail\n"; my $wpa = ($SAILDATA[$higha][$wind][$sail] - $SAILDATA[$lowa][$wind][$sail])/($higha-$lowa); for my $j (1..$higha-$lowa-1) { $SAILDATA[$lowa+$j][$wind][$sail] = $SAILDATA[$lowa][$wind][$sail] + $j*$wpa; } } } } my $j = 0; #print Dumper($SAILC[$pro]); for my $i (0, 1, @{$SAILC[$pro]}) { # warn "$i\n"; interpolate_sail_wind($i); interpolate_sail($i); } my @IDEAL; if ($gen_h) { print "static float polar_chart_${pro}[181][130]= {"; } my $h_sail = "static char best_sail_${pro}[181][130]= {"; for my $i (0..180) { if ($gen_h) { print '{ '; $h_sail .= "{"; } else { print "$i;"; } for my $j (0..MAX_WIND) { my $best_sail; my $best_speed = (sort {$b <=> $a} @{$SAILDATA[$i][$j]})[0]; $IDEAL[$i][$j][0] = $best_speed; for my $k (0..$#{$SAILDATA[$i][$j]}) { if ( ${$SAILDATA[$i][$j]}[$k] == $best_speed) { $best_sail = $k; $IDEAL[$i][$j][1] = $best_sail; last; } } if ($gen_h) { printf("%.3f,", $best_speed); $h_sail .= $best_sail . ","; } else { printf("%.2f:%s;", $best_speed, $best_sail); } } if ($gen_h) { print "},"; $h_sail .= "},\n" } print "\n"; } if ($gen_h) { print "};\n\n"; print $h_sail . "};\n\n"; } exit unless $gen_h; my (@BU, @BD); for my $i (0..MAX_WIND) { my $bu = 0; my $bd = 0; my $bus = 0; my $bds = 0; for my $j (0..180) { my $us = $IDEAL[$j][$i][0] * cos($j*PI/180); my $ds = -$IDEAL[$j][$i][0] * cos($j*PI/180); if ($us > $bus) { $bus = $us; $bu = $j; } if ($ds > $bds) { $bds = $ds; $bd = $j; } } $BU[$i] = $bu; $BD[$i] = $bd; } $BU[0] = $BU[1]; $BD[0] = $BD[1]; print "\n"; print "static unsigned best_upwind_${pro}[POLAR_COUNT] = { " . join(',', @BU) . "};\n"; print "static unsigned best_downwind_${pro}[POLAR_COUNT] = { " . join(',', @BD) . "};\n"; my (@F,@L); for my $i (0..MAX_WIND) { my $ll = 0; for (my $j = 35; $j <= 165; $j += 5) { # if ($j - $BU[$i] >= 2 && $j - $BU[$i] <= 6) { if ($j - $BU[$i] > 0 && $j - $BU[$i] <= 5) { $F[$i] = $ll = ($j-35)/5; # } elsif ($BD[$i] - $j >= 2 && $BD[$i] - $j <= 6) { } elsif ($BD[$i] - $j > 0 && $BD[$i] - $j <= 5) { $L[$i] = ($j-35)/5 - $ll + 1; } } } print "static unsigned first_angle_${pro}[POLAR_COUNT] = {" . join(',', @F) . "};\n"; print "static unsigned angle_count_${pro}[POLAR_COUNT] = {" . join(',', @L) . "};\n";