Title: Universal Conversion Class (Temperature,Distance etc.)
Question: This article serves to demonstrate how to create a class that can view a value as many different conversions, much in the way that DELPHI's AsString and AsInteger properties. I have only included some Temperature and Distance conversions here (there may be errors in the formulas) as my purpose is to demonstrate how to add new conversions to the class.
The nice thing about the class is that you can group ALL your conversions into one object and is easy to add new functionality as needed. eg. Volumes,Deg-Rad etc.
// Example using 1.8 miles as a base value
procedure TForm1.Button2Click(Sender: TObject);
var C : TConvertor;
begin
C := TConvertor.Create;
C.SetValue(1.8,cvMiles);
memo1.lines.add(FormatFloat('######0.000000000',C.AsInches));
memo1.lines.add(FormatFloat('######0.000000000',C.AsFeet));
memo1.lines.add(FormatFloat('######0.000000000',C.AsYards));
memo1.lines.add(FormatFloat('######0.000000000',C.AsMiles));
memo1.lines.add(FormatFloat('######0.000000000',
C.AsMilimeters));
memo1.lines.add(FormatFloat('######0.000000000',
C.AsCentimeters));
memo1.lines.add(FormatFloat('######0.000000000',C.AsMeters));
memo1.lines.add(FormatFloat('######0.000000000',
C.AsKilometers));
memo1.lines.add(FormatFloat('######0.000000000',
C.AsNauticalMiles));
C.Free;
end;
Answer:
unit ConvLib;
interface
uses Classes,Math;
type
TConvertorBaseType = (cvFarenheit,cvCelsius,cvKelvin, // Temp
cvInches,cvFeet,cvYards,cvMiles, // Dist
cvMilimeters,
cvCentimeters,cvMeters,
cvKilometers,cvNauticalMiles
);
TConvertorBaseTypes = set of TConvertorBaseType;
TConvertor = class(TObject)
private
FValue : extended;
FBaseType : TConvertorBaseType;
function BaseTypeOk(BT : TConvertorBaseTypes) : boolean;
function GetCelsius : extended;
function GetFarenheit : extended;
function GetKelvin : extended;
function GetInches : extended;
function GetFeet : extended;
function GetMiles : extended;
function GetYards : extended;
function GetMilimeters : extended;
function GetCentimeters : extended;
function GetMeters : extended;
function GetKilometers : extended;
function GetNauticalMiles : extended;
public
procedure SetValue(Value : extended;
BaseType : TConvertorBaseType);
// Temperature
property AsCelsius : extended read GetCelsius;
property AsKelvin : extended read GetKelvin;
property AsFarenheit : extended read GetFarenheit;
// Distance
property AsInches : extended read GetInches;
property AsFeet : extended read GetFeet;
property AsYards : extended read GetYards;
property AsMiles : extended read GetMiles;
property AsMilimeters : extended read GetMilimeters;
property AsCentimeters : extended read GetCentimeters;
property AsMeters : extended read GetMeters;
property AsKilometers : extended read GetKilometers;
property AsNauticalMiles : extended read GetNauticalMiles;
end;
// -----------------------------------------------------------------------------
implementation
// ===========================================================
// Set value to convert and what base type it is
// eg. Kilometers,GallonsUK etc.
// ===========================================================
procedure TConvertor.SetValue(Value : extended;
BaseType : TConvertorBaseType);
begin
FValue := Value;
FBaseType := BaseType;
end;
// ==============================================
// Check if Base type is valid for conversion
// ==============================================
function TConvertor.BaseTypeOk(BT : TConvertorBaseTypes) : boolean;
begin
if not (FBaseType in BT) then begin
raise EInvalidArgument.Create('Invalid Base Type for TConvertor');
end
else
Result := true;
end;
// ===========================
// Convertor methods
// ===========================
function TConvertor.GetCelsius : extended;
var Retvar : extended;
begin
RetVar := 0.0;
if BaseTypeOk([cvCelsius,cvKelvin,cvFarenheit]) then begin
case FBaseType of
cvCelsius : RetVar := FValue; // converts to self
cvKelvin : RetVar := FValue - 273.15;
cvFarenheit : Retvar := (5.0 / 9.0) * (FValue - 32.0);
end;
end;
Result := RetVar;
end;
function TConvertor.GetFarenheit : extended;
var Retvar : extended;
begin
RetVar := 0.0;
if BaseTypeOk([cvCelsius,cvKelvin,cvFarenheit]) then begin
case FBaseType of
cvFarenheit : RetVar := FValue; // converts to self
cvKelvin : RetVar := ((9.0 / 5.0) * (FValue - 273.15)) + 32.0;
cvCelsius : Retvar := ((9.0 / 5.0) * FValue) + 32.0;
end;
end;
Result := RetVar;
end;
function TConvertor.GetKelvin : extended;
var Retvar : extended;
begin
RetVar := 0.00;
if BaseTypeOk([cvCelsius,cvKelvin,cvFarenheit]) then begin
case FBaseType of
cvKelvin : RetVar := FValue; // converts to self
cvFarenheit : RetVar := ((5.0 / 9.0) * (FValue - 32.0)) + 273.15;
cvCelsius : Retvar := FValue + 273.15;
end;
end;
Result := RetVar;
end;
function TConvertor.GetInches : extended;
var Retvar : extended;
begin
RetVar := 0.00;
if BaseTypeOk([cvInches,cvFeet,cvYards,cvMiles,
cvMilimeters,cvCentimeters,cvMeters,
cvKilometers,cvNauticalMiles]) then begin
case FBaseType of
cvInches : RetVar := FValue; // converts to self
cvFeet : RetVar := FValue * 12.0;
cvYards : Retvar := FValue * 12.0 * 3.0;
cvMiles : RetVar := FValue * 12.0 * 3.0 * 1760.0;
cvCentimeters : RetVar := FValue / 2.54;
cvMeters : RetVar := (FValue / 0.3048) * 12.0;
cvKilometers : RetVar := (FValue / 1.609344) * 12.0 * 3.0 * 1760.0;
cvNauticalMiles : RetVar := ((FValue * 1.852) / 1.609344) * 12.0 *
3.0 * 1760.0;
end;
end;
Result := RetVar;
end;
function TConvertor.GetFeet : extended;
begin
if FBaseType = cvFeet then
Result := FValue
else
Result := GetInches / 12.0;
end;
function TConvertor.GetYards : extended;
begin
if FBaseType = cvYards then
Result := FValue
else
Result := GetInches / 12.0 / 3.0;
end;
function TConvertor.GetMiles : extended;
var Retvar : extended;
begin
RetVar := 0.00;
if BaseTypeOk([cvInches,cvFeet,cvYards,cvMiles,
cvMilimeters,cvCentimeters,cvMeters,
cvKilometers,cvNauticalMiles]) then begin
case FBaseType of
cvMiles : RetVar := FValue; // converts to self
cvInches : RetVar := FValue / 12.0 / 3.0 / 1760.0;
cvFeet : Retvar := FValue / 3.0 / 1760.0;
cvYards : RetVar := FValue / 1760.0;
cvCentimeters : RetVar := (FValue / 2.54) / 12.0 / 3.0 / 1760.0;
cvMeters : RetVar := FValue / 0.3048 / 3.0 / 1760.0;
cvKilometers : RetVar := (FValue / 1.609344) ;
cvNauticalMiles : RetVar := ((FValue * 1.852) / 1.609344);
end;
end;
Result := RetVar;
end;
function TConvertor.GetCentimeters : extended;
var Retvar : extended;
begin
RetVar := 0.00;
if BaseTypeOk([cvInches,cvFeet,cvYards,cvMiles,
cvMilimeters,cvCentimeters,cvMeters,
cvKilometers,cvNauticalMiles]) then begin
case FBaseType of
cvCentimeters : RetVar := FValue; // converts to self
cvInches : RetVar := FValue * 2.54;
cvFeet : RetVar := FValue * 2.54 * 12.0;
cvYards : Retvar := FValue * 2.54 * 12.0 * 3.0;
cvMiles : RetVar := FValue * 2.54 * 12.0 * 3.0 * 1760.0;
cvMeters : RetVar := FValue * 100.0;
cvKilometers : RetVar := FValue * 1000.0 * 100.0;
cvNauticalMiles : RetVar := (FValue * 1.852) * 1000.0 * 100.0;
end;
end;
Result := RetVar;
end;
function TConvertor.GetMilimeters : extended;
begin
if FBaseType = cvMilimeters then
Result := FValue
else
Result := GetCentimeters * 10.0;
end;
function TConvertor.GetMeters : extended;
begin
if FBaseType = cvMeters then
Result := FValue
else
Result := GetCentimeters / 100.0;
end;
function TConvertor.GetKilometers : extended;
begin
if FBaseType = cvKilometers then
Result := FValue
else
Result := GetMeters / 1000.0;
end;
function TConvertor.GetNauticalMiles : extended;
begin
if FBaseType = cvNauticalMiles then
Result := FValue
else
Result := GetKilometers / 1.852;
end;
end.