diff --git a/PABCNetHelp/LangGuide/Operations_Expressions/IfOperation.html b/PABCNetHelp/LangGuide/Operations_Expressions/IfOperation.html index 8e296008b..dacdcbe58 100644 --- a/PABCNetHelp/LangGuide/Operations_Expressions/IfOperation.html +++ b/PABCNetHelp/LangGuide/Operations_Expressions/IfOperation.html @@ -7,7 +7,7 @@

Óñëîâíàÿ îïåðàöèÿ

-

Óñëîâíàÿ îïåðàöèÿ èìååò ñëåäóþùèé âèä:

+

Óñëîâíàÿ îïåðàöèÿ (ïåðâàÿ ôîðìà) èìååò ñëåäóþùèé âèä:

óñëîâèå ? âûðàæåíèå1 : âûðàæåíèå2
@@ -25,4 +25,30 @@ min := a
else min := b;

+

Êðîìå òîãî, èìååòñÿ âòîðàÿ ôîðìà óñëîâíîé îïåðàöèè â +ñèíòàêñèñå Ïàñêàëÿ:

+
+ if + óñëîâèå then âûðàæåíèå1 else âûðàæåíèå2 +
+

Íàïðèìåð:

+
+

var min := if a < b then a + else b;

+
+

Ðåêîìåíäóåòñÿ èñïîëüçîâàòü âòîðóþ ôîðìó óñëîâíîé îïåðàöèè.

+

Îãðàíè÷åíèå. Âòîðóþ ôîðìó óñëîâíîé îïåðàöèè íåëüçÿ +èñïîëüçîâàòü â êà÷åñòâå âûðàæåíèÿ âåðõíåãî óðîâíÿ â ëÿìáäàõ. Ñëåäóþùèé êîä +îøèáî÷åí:

+
+

var l: real -> real := x -> if x<0 + then 0 else x;

+
+

Äëÿ ðåøåíèÿ óêàçàííîé ïðîáëåìû ìîæíî âçÿòü óñëîâíóþ îïåðàöèþ â ñêîáêè:

+
+

var l: real -> real := x -> (if x<0 + then 0 else x);

+
+

 

+ \ No newline at end of file diff --git a/bin/Lib/GraphWPF.pas b/bin/Lib/GraphWPF.pas index b5e61a2cd..bd0a22ae2 100644 --- a/bin/Lib/GraphWPF.pas +++ b/bin/Lib/GraphWPF.pas @@ -416,8 +416,12 @@ function TextSize(text: string): Size; // ----------------------------------------------------- /// Рисует график функции f, заданной на отрезке [a,b] по оси абсцисс и на отрезке [min,max] по оси ординат, в прямоугольнике, задаваемом координатами x1,y1,x2,y2, procedure DrawGraph(f: real -> real; a, b, min, max, x, y, w, h: real); +/// Рисует график функции f, заданной на отрезке [a,b] по оси абсцисс и на отрезке [min,max] по оси ординат, в прямоугольнике, задаваемом параметрами x,y,w,h. Два последних параметра задают шаг сетки по OX и OY +procedure DrawGraph(f: real -> real; a, b, min, max, x, y, w, h: real; XTicks: real; YTicks: real); /// Рисует график функции f, заданной на отрезке [a,b] по оси абсцисс и на отрезке [min,max] по оси ординат, в прямоугольнике r procedure DrawGraph(f: real -> real; a, b, min, max: real; r: GRect); +/// Рисует график функции f, заданной на отрезке [a,b] по оси абсцисс и на отрезке [min,max] по оси ординат, в прямоугольнике r. Два последних параметра задают шаг сетки по OX и OY +procedure DrawGraph(f: real -> real; a, b, min, max: real; r: GRect; XTicks, YTicks: real); /// Рисует график функции f, заданной на отрезке [a,b] по оси абсцисс и на отрезке [min,max] по оси ординат, на полное графическое окно procedure DrawGraph(f: real -> real; a, b, min, max: real); /// Рисует график функции f, заданной на отрезке [a,b], в прямоугольнике, задаваемом координатами x1,y1,x2,y2, @@ -1168,86 +1172,127 @@ procedure TextOut(x, y: real; text: real; c: GColor; align: Alignment; angle: re type FS = auto class - mx, my, a, min, max: real; - x1, y1: real; - f: real-> real; + mx, my, a, b, min, max: real; + x, y, w, h, XTicks, YTicks: real; + f: real -> real; + marginY := 6; + marginX := 6; + spaceBetweenTextAndGraph := 4; - function Apply(x: real) := Pnt(x1 + mx * (x - a), y1 + my * (max - f(x))); - function RealToScreenX(x: real) := x1 + mx * (x - a); - function RealToScreenY(y: real) := y1 - my * (y + min); + constructor (a, b, min, max, x, y, w, h: real; f: real -> real; XTicks: real := 1; YTicks: real := 1); + begin + Self.a := a.Round(5); Self.b := b.Round(5); + Self.min := min.Round(5); Self.max := max.Round(5); + Self.x := x; Self.y := y; Self.w := w; Self.h := h; + Self.f := f; Self.XTicks := XTicks; Self.YTicks := YTicks; + end; + + function Ticks(d: real): real; + begin + var n := floor(log10(d)); + var p := Power(10,n); + var r := d / p; + // r = 1 .. 10 + if r >= 5 then + Result := p + else if r >= 2 then + Result := p/2 + else Result := p/5 + end; + + procedure CorrectBounds; + begin + var digits := 5; + var tw := TextWidth('-99.9'); + w -= marginX * 2 + spaceBetweenTextAndGraph + tw; + h -= marginY * 2 + spaceBetweenTextAndGraph + TextHeight('0'); + x += marginX + spaceBetweenTextAndGraph + tw; + y += marginY; + mx := w / (b - a); + my := h / (max - min); + if real.IsNaN(XTicks) then + XTicks := Ticks(b-a); + if real.IsNaN(YTicks) then + YTicks := Ticks(max-min); + end; + + function Apply(xx: real) := Pnt(x + mx * (xx - a), y + my * (max - f(xx))); + function RealToScreenX(xx: real) := x + mx * (xx - a); + function RealToScreenY(yy: real) := y + h - my * (yy - min); // ? + function ScreenToRealX(xx: real) := (xx - x) / mx + a; + function ScreenToRealY(yy: real) := (y + h - yy) / my + min; + + procedure Draw; + begin + FillRectangle(x, y, w, h, Colors.White); + CorrectBounds; + Pen.Color := Colors.LightGray; + var sx := mx * XTicks; + var xt := XTicks * Trunc(Abs(a)/XTicks); + var rx0: real; + if a <= 0 then + rx0 := -xt + else rx0 := xt + XTicks; + //var rx0 := a; + var x0 := RealToScreenX(rx0); + while x0<=x+w+0.000001 do + begin + Line(x0,y,x0,y+h); + TextOut(x0,y+h+4,rx0.Round(3),Alignment.CenterTop); + x0 += sx; + rx0 += XTicks; + end; + + var sy := my * YTicks; + var yt := YTicks * Trunc(Abs(min)/YTicks); + var ry0: real; + if min <= 0 then + ry0 := -yt + else ry0 := yt + YTicks; + //var ry0 := min; + //var y0 := y + h; + var y0 := RealToScreenY(ry0); + while y0>=y-0.000001 do + begin + Line(x,y0,x+w,y0); + TextOut(x-4,y0,ry0.Round(5),Alignment.RightCenter); + y0 -= sy; + ry0 += YTicks; + end; + + DrawRectangle(x, y, w, h,Colors.Black); + + Pen.Color := Colors.Black; + var n := Round(w / 1); + var pp := PartitionPoints(a, b, n); + var fff: real -> Point := xx -> Pnt(x + mx * (xx - a), y + my * (max - f(xx).Clamp(min,max))); + Polyline(pp.Select(fff).ToArray); + end; end; -/// Рисует график функции f, заданной на отрезке [a,b] по оси абсцисс и на отрезке [min,max] по оси ординат, в прямоугольнике, задаваемом параметрами x,y,w,h, -procedure DrawGraph(f: real-> real; a, b, min, max, x, y, w, h: real); +/// Рисует график функции f, заданной на отрезке [a,b] по оси абсцисс и на отрезке [min,max] по оси ординат, в прямоугольнике, задаваемом параметрами x,y,w,h +procedure DrawGraph(f: real -> real; a, b, min, max, x, y, w, h: real); begin - var coefx := w / (b - a); - var coefy := h / (max - min); - - var fso := new FS(coefx, coefy, a, min, max, x, y, f); - - // Линии - {Pen.Color := Color.LightGray; - - var hx := 1.0; - var xx := hx; - while xxa do - begin - var x0 := fso.RealToScreenX(xx); - Line(x0,y1,x0,y2); - xx -= hx - end; - - var hy := 1.0; - var yy := hy; - while yymin do - begin - var y0 := fso.RealToScreenY(yy); - Line(x1,y0,x2,y0); - yy -= hy - end; - - // Оси - Pen.Color := Color.Blue; - - var x0 := fso.RealToScreenX(0); - var y0 := fso.RealToScreenY(0); - - Line(x0,y1,x0,y2); - Line(x1,y0,x2,y0);} - - // График - - Pen.Color := Colors.Black; - Rectangle(x, y, w, h); - - Pen.Color := Colors.Black; - var n := Round(w / 3); - Polyline(PartitionPoints(a, b, n).Select(fso.Apply).ToArray); + var fso := new FS(a,b,min,max,x,y,w,h,f,real.NaN,real.NaN); + fso.Draw; +end; + +/// Рисует график функции f, заданной на отрезке [a,b] по оси абсцисс и на отрезке [min,max] по оси ординат, в прямоугольнике, задаваемом параметрами x,y,w,h. Два последних параметра задают шаг сетки по OX и OY +procedure DrawGraph(f: real -> real; a, b, min, max, x, y, w, h, XTicks, YTicks: real); +begin + var fso := new FS(a,b,min,max,x,y,w,h,f,XTicks,YTicks); + fso.Draw; end; procedure DrawGraph(f: real -> real; a, b, min, max: real; r: GRect) := DrawGraph(f, a, b, min, max, r.X, r.Y, r.Width, r.Height); +procedure DrawGraph(f: real -> real; a, b, min, max: real; r: GRect; XTicks, YTicks: real) := DrawGraph(f, a, b, min, max, r.X, r.Y, r.Width, r.Height, XTicks, YTicks); + procedure DrawGraph(f: real -> real; a, b, min, max: real) := DrawGraph(f, a, b, min, max, Window.ClientRect); procedure DrawGraph(f: real -> real; a, b: real; x, y, w, h: real); begin - var n := Round(w / 3); + var n := Round(w / 1); var q := PartitionPoints(a, b, n); DrawGraph(f, a, b, q.Min(f), q.Max(f), x, y, w, h) end;