Program AAT_Speed_Task; // GNZ AAT Speed task. // // For Open/18m/15m/Standard classes // //*************************************************************************** // Gliding New Zealand - AAT (Area Assigned Task) Speed task. // Version: 1.0.0.1 // Created: 16/11/02 // Author: Lex McPhail // E-mail: lex@ssiltd.co.nz // // ChangeLog: // 16/11/02 - Lex - create script from IGC and GNZ published rules. // Notes: // - currently this task is not specified in the GNZ rules - SRC (Sailplane // Racing Committee) meeting on 16/11/02 approved the use of the IGC rules // with modifications (mainly Day Factor calculations). // - uses the Day Tag field to specify the minimum hours for the task. This // *MUST* be specified else no points will be calculated. // - uses the same var notation as published in the GNZ rules, except for // _Do, _Vo, _To, _Ho which have a _ prefixed as Do and To are script // commands. //*************************************************************************** var i : integer; _Do, Dm, Dh, Dc, _Vo, Vh, _To, Td, _Ho, Pm, Pvm, Pdm, Pv, Pd, Pts, T , M, F, N, n1, n2, x : Double; Function MinValue( a,b,c : double ) : double; var m : double; begin m := 9999999; If a < m Then m := a; If b < m Then m := b; If c < m Then m := c; MinValue := m; end; begin // - min hcap dist needed. 80km Dm := 80000; // - min task time. Hrs in the Day Tag. Td := StrToFloat(DayTag) * 3600; If Td <= 0 Then begin Info1 := 'Day Tag does not have a valid minimum hours for the task.'; Info2 := 'DayTag = ' + DayTag; Info3 := 'Td = ' + FormatFloat('0.000',Td); Exit; end; // 3 hrs in secs. // Td := 10800; // - no outlanding penalty. M := 0; // - find the highest hcap in class (Ho) & num competitors launched (N). N := 0; _Ho := 0; for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin If Pilots[i].Hcap > _Ho Then _Ho := Pilots[i].Hcap; // --- num launched. If Pilots[i].takeoff > 0 Then N := N+1; end; end; // - nobody launched - stop here. If N=0 Then Exit; // - calc the factors that determine the max points possible for today. _Do := 0; _Vo := 0; _To := 0; n1 := 0; n2 := 0; for i:=0 to GetArrayLength(Pilots)-1 do begin If not Pilots[i].isHC Then begin // --- hcap distance. Dh := Pilots[i].dis * _Ho / Pilots[i].Hcap; // --- corrected distance. Dc := Dh - M; Pilots[i].sdis := Dc; // --- max corrected distance. If Dc > _Do Then _Do := Dc; // --- num got further than min distance. If Dh > Dm Then n1 := n1 + 1; // --- if finished calc speed and duration. If Pilots[i].finish > 0 Then begin // ---- marking time. T := Pilots[i].finish - Pilots[i].start; If T < Td Then T := Td; // ---- hcap speed. Vh := Dh / T; Pilots[i].sspeed := Vh; // ---- max hcap speed. If Vh > _Vo Then begin _Vo := Vh; _To := T; end Else begin If Vh = _Vo Then begin If T < _To Then _To := T; end; end; // ---- num that went faster that 2/3 of highest speed. If Vh > ((2/3) * _Vo) Then n2 := n2 + 1; end; end; end; // - Day factor. // this is the IGC calc: F := 1.25 * n1 / N; // GNZ is harsher??? F := 2 * n1 / N - 0.5; If F > 1 Then F := 1; If F < 0 Then F := 0; // - max score possible. If _To>0 Then Pm := MinValue( 1000.0, (6 * (_Do/1000)) - 200, (600 * (_To/3600)) - 200 ) Else begin x := (6 * (_Do/1000)) - 200; If x>1000 Then Pm := 1000 Else Pm := x; end; // - max speed points. Pvm := (2/3) * (n2/N) * Pm; // - max distance points. Pdm := Pm - Pvm; // - set pilots points, etc. for i:=0 to GetArrayLength(Pilots)-1 do begin Dc := Pilots[i].sdis; If Pilots[i].finish > 0 Then begin // --- finisher speed calc with distance component. Vh := Pilots[i].sspeed; x := (2/3) * _Vo; If Vh < x Then Pv := 0 Else Pv := Pvm * (Vh - x) / (_Vo/3); x := (2/3) * _Do; If Dc < x Then Pd := Pdm * Dc / x Else Pd := Pdm; end Else begin // --- non-finisher distance points only. Pv := 0; If _Do <= 0 then Pd := 0 Else Pd := Pdm * (Dc/_Do); end; // -- points. Pts := Round( F * (Pv + Pd) ) - Pilots[i].penalty; If Pts < 0 Then Pts := 0; Pilots[i].Points := Pts; // -- start time. Pilots[i].sstart:=Pilots[i].start; // -- finish time. Pilots[i].sfinish:=Pilots[i].finish; end; Info1 := 'Maximum Points: '+IntToStr(Round(Pm)) + ' Pvm: '+IntToStr(Round(Pvm)) + ' Pdm: '+IntToStr(Round(Pdm)); Info2 := 'Day factor = '+FormatFloat('0.000',F); Info3 := 'N = '+FormatFloat('0.000',N) + ' n1 = '+FormatFloat('0.000',n1) + ' n2 = '+FormatFloat('0.000',n2) + ' n1/N = '+FormatFloat('0.000',n1/N); // i := 2; // Info4 := 'Pilot tag=' + Pilots[i].tag + 'sdis=' + FormatFloat('0.00000',Pilots[i].sdis) + ' tdis=' + FormatFloat('0.00000',Pilots[i].tdis) + ' dis=' + FormatFloat('0.00000',Pilots[i].dis); // Info4 := 'N1=' + IntToStr(Round(N1)) + ' N2=' + IntToStr(Round(N2)); end.