diff --git a/2.10/Source/varPerspective.pas b/2.10/Source/varPerspective.pas new file mode 100644 index 0000000..a3cad69 --- /dev/null +++ b/2.10/Source/varPerspective.pas @@ -0,0 +1,144 @@ +unit varPerspective; + +interface + +uses + BaseVariation, XFormMan; + +const + var_a_name='perspective_angle'; + var_f_name='perspective_dist'; + +type + TVariationPerspective = class(TBaseVariation) + private + angle, focus: double; + vsin, vf, vfcos: double; + + public + constructor Create; + + class function GetName: string; override; + class function GetInstance: TBaseVariation; override; + + class function GetNrVariables: integer; override; + class function GetVariableNameAt(const Index: integer): string; override; + + function SetVariable(const Name: string; var value: double): boolean; override; + function GetVariable(const Name: string; var value: double): boolean; override; + + procedure CalcFunction; override; + procedure Prepare; override; + end; + +implementation + +uses + math; + +// TVariationPerspective + +/////////////////////////////////////////////////////////////////////////////// +constructor TVariationPerspective.Create; +begin + angle := random; + focus := 2*random + 1; +end; + +procedure TVariationPerspective.Prepare; +begin + vsin := sin(angle*pi/2); + vf := vvar * focus; + vfcos := vf * cos(angle*pi/2); +end; + +procedure TVariationPerspective.CalcFunction; +{$if false} +var + t: double; +begin + t := (focus - fty^*vsin); + FPx^ := FPx^ + vf * ftx^ / t; + FPy^ := FPy^ + vfcos * fty^ / t; +{$else} +asm + mov ecx, [eax + FTy] + fld qword ptr [ecx] + fld st + fmul qword ptr [eax + vsin] + fsubr qword ptr [eax + focus] + fld st + mov ecx, [eax + FTx] + fdivr qword ptr [ecx] + fmul qword ptr [eax + vf] + mov ecx, [eax+FPx] + fadd qword ptr [ecx] + fstp qword ptr [ecx] + fdivp st(1), st + fmul qword ptr [eax + vfcos] + mov ecx, [eax+FPy] + fadd qword ptr [ecx] + fstp qword ptr [ecx] + fwait +{$ifend} +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPerspective.GetInstance: TBaseVariation; +begin + Result := TVariationPerspective.Create; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPerspective.GetName: string; +begin + Result := 'perspective'; +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPerspective.GetVariableNameAt(const Index: integer): string; +begin + case Index of + 0: Result := var_a_name; + 1: Result := var_f_name; + else + Result := ''; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPerspective.SetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_a_name then begin + angle := Value; + Result := True; + end else if Name = var_f_name then begin + focus := Value; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +class function TVariationPerspective.GetNrVariables: integer; +begin + Result := 2; +end; + +/////////////////////////////////////////////////////////////////////////////// +function TVariationPerspective.GetVariable(const Name: string; var value: double): boolean; +begin + Result := False; + if Name = var_a_name then begin + Value := angle; + Result := True; + end else if Name = var_f_name then begin + Value := focus; + Result := True; + end +end; + +/////////////////////////////////////////////////////////////////////////////// +initialization + RegisterVariation(TVariationPerspective); +end.