Re: compute trigonometric in Delphi

Posted by webmaster Guido on March 27, 2005

In Reply to: Re: Have 5 Parameters Select any two to compute results posted by Lionel on March 25, 2005

A User will be given two values that were measured in the field and the rest have to be computed.

Most of the time the Angle is measured and the Tangent distance is measured but sometimes someone will bring in a measured Chord and Tangent or a Radius and Angle and the rest of the parameters have to be computed but the user never knows which two values he will receive of the possible 5.

Let's declare some unit-wide variables for the parameters:

implementation
{$R *.DFM}
var
  An, Ra, Tg, Ar, Ch: real;
  // Which parameters are given?
  AnGiven, RaGiven, TgGiven, ArGiven, ChGiven: Boolean;
  // How many parameters are given and valid?
  ParamsGiven: integer;

Some example Delphi code for the calculate-button:

procedure TForm1.btnCalcClick(Sender: TObject);
begin
  AnalyzeData; // count valid numbers and save in variables
  if ValidEntries  2 then
    ShowMessage('Too many data. Give me only 2 valid numbers.')
  else begin
    Calculate;
    ShowResults;
  end;
end;

Convert the text of the edit-boxes to numbers, remember which parameters are given and valid, and count the given parameters:

procedure TForm1.AnalyzeData;
var
  ErrorCode: integer;
begin
  ParamsGiven := 0;
  Val(Edit1.Text, An, ErrorCode); AnGiven := ErrorCode = 0;
  Val(Edit2.Text, Ra, ErrorCode); RaGiven := ErrorCode = 0;
  Val(Edit3.Text, Tg, ErrorCode); TgGiven := ErrorCode = 0;
  Val(Edit4.Text, Ar, ErrorCode); ArGiven := ErrorCode = 0;
  Val(Edit5.Text, Ch, ErrorCode); ChGiven := ErrorCode = 0;
  if AnGiven then inc(ParamsGiven);
  if RaGiven then inc(ParamsGiven);
  if TgGiven then inc(ParamsGiven);
  if ArGiven then inc(ParamsGiven);
  if ChGiven then inc(ParamsGiven);
end;

Calculate the 3 missing parameters from the 2 given entries.
I searched only for a couple of formulas. It's up to you to cook up the rest ;-)
Also add some error-checking, for example: no divide-by zero.

procedure TForm1.Calculate;  
begin    
  if AnGiven then      // if angle is given
     An := DegToRad(An)    // convert to radians
  else begin           // if angle is missing
    if RaGiven then begin
      if TgGiven then An := Ra + Tg       // fake
      else if ArGiven then An := Ar / Ra  
      else An := Ra + Ch;                 // fake
    end
    else if TgGiven then begin
      if ArGiven then An := Tg + Ar  // fake
      else An := Tg + Ch;            // fake
    end
    else
      An := Ar + Ch;  // fake
  end;
  if not RaGiven then begin // if radius is missing
    if AnGiven then begin
      if TgGiven then Ra := An + Tg       // fake
      else if ArGiven then Ra := Ar / An  
      else Ra := An + Ch;                 // fake
    end
    else if TgGiven then begin
      if ArGiven then Ra := Tg + Ar // fake
      else Ra := Tg + Ch;           // fake
    end
    else
      Ra := Ar + Ch;  // fake
  end;
  if not TgGiven then Tg := Tan(An) * Ra;
  if not ArGiven then Ar := An * Ra;
  if not ChGiven then Ch := Sqrt(2 * Ra - Ra * Ra * Cos(An));
end;

If you only show the parameters that were calculated, and not redisplay the originally given values, it's less confusing for the user. Otherwise, the display could be changed by formatting the numbers.

procedure TForm1.ShowResults;
begin
  if not AnGiven then begin
    An := RadToDeg(An);  // show angle in degrees
    Edit1.Text := FloatToStr(An);
  end;
  if not RaGiven then Edit2.Text := FloatToStr(Ra);
  if not TgGiven then Edit3.Text := FloatToStr(Tg);
  if not ArGiven then Edit4.Text := FloatToStr(Ar);
  if not ChGiven then Edit5.Text := FloatToStr(Ch);
end;

Good luck!
Guido

Related Articles and Replies