function TBoltApproximationD3.Calc: boolean;
// KX = 0 .. 1;
const
cnst = 1000;
cnstdKxV = 0.001;
cnstdAlpha = Pi / 180;
cEps = 0.0001;
cTopLeft = 0;
cTopRight = 3;
cBottomLeft = 1;
cBottomRight = 2;
var
Exchanged: boolean;
Alpha, dAlpha, KxV, dKxV, xV, SumMx, SumMy, ForceCenterX, Temp: double;
begin
Result := false;
ResultClear;
if CanCalc
then
begin
Exchanged := false;
if GetAlpha > Pi / 4
then
begin
Exchanged := true;
Exchange(FMx, FMy);
Exchange(
FB, FD);
Exchange(FC1, FD1);
end;
try
FPoints.Fyd := FFy;
// Alpha;
dAlpha := cnstdAlpha;
Alpha := -dAlpha;
SumMy := 0;
repeat
Alpha := Alpha + dAlpha;
FPoints.Alpha := Alpha;
// Rad;
FPoints.Count := 4;
FPoints.X[cTopLeft] := FD1 / cnst;
FPoints.Y[cTopLeft] := -FC1 / cnst;
FPoints.X[cBottomLeft] := FD1 / cnst;
FPoints.Y[cBottomLeft] := -FD / cnst + FC1 / cnst;
FPoints.X[cBottomRight] :=
FB / cnst - FD1 / cnst;
FPoints.Y[cBottomRight] := -FD / cnst + FC1 / cnst;
FPoints.X[cTopRight] :=
FB / cnst - FD1 / cnst;
FPoints.Y[cTopRight] := -FC1 / cnst;
// KxV;
dKxV := cnstdKxV;
KxV := -dKxV;
SumMx := 0;
repeat
KxV := KxV + dKxV;
xV := KxV * FPoints.MaxH;
// m;
FPoints.xV := xV;
if FUsePolyeder
then
begin
FPoints.SigmaD := Min(FFy * cnst, FFy * cnst * xV / (FPoints.MaxH - xV));
FPoints.Force := FPolyeder.SolidStressFromRect(
FB / cnst, FD / cnst, xV, FPoints.SigmaD, Alpha);
ForceCenterX := FPolyeder.Center.X;
end
else
begin
FPoints.SigmaD := 0.5 * Min(FFy * cnst, FFy * cnst * xV / (FPoints.MaxH - xV));
FPoints.Force := FPolygon.SimplifiedStressFromRect(
FB / cnst, FD / cnst, xV, FPoints.SigmaD, Alpha);
ForceCenterX := FPolygon.CenterX;
end;
Temp := Abs(FMx) - FPoints.SumMx;
if SumMx * Temp < 0
then
dKxV := -dKxV / 2;
SumMx := Temp;
Result := (CompareValue(KxV, 0) >= 0)
and (CompareValue(KxV, 1) <= 0);
until (Abs(SumMx) < cEps)
or (
not Result);
if Result
then
begin
Temp := Abs(FMy) - FPoints.SumMy + FPoints.Force * ForceCenterX;
if SumMy * Temp < 0
then
dAlpha := -dAlpha / 2;
SumMy := Temp;
end;
Result := (CompareValue(Alpha, 0) >= 0)
and (CompareValue(Alpha, Pi / 2) <= 0);
until (Abs(SumMy) < cEps)
or (
not Result);
finally
if Exchanged
then
begin
Exchange(FMx, FMy);
Exchange(
FB, FD);
Exchange(FC1, FD1);
end;
if not Result
then
ResultClear;
end;
end;
end;