Skip to content

Instantly share code, notes, and snippets.

@hodzanassredin
Last active May 10, 2023 13:25
Show Gist options
  • Save hodzanassredin/c8211ae45a88bb60c3a631a9efa9b378 to your computer and use it in GitHub Desktop.
Save hodzanassredin/c8211ae45a88bb60c3a631a9efa9b378 to your computer and use it in GitHub Desktop.
learning black box
MODULE LinalgGraph;
IMPORT v :=LinalgVector, p:= LinalgPolygon, Views, Ports, StdLog, Strings, Fonts, TextControllers, TextMappers,Properties;
CONST pointSize = Ports.point * 20;
TYPE
View = POINTER TO RECORD (Views.View) END;
Polygons* = POINTER TO RECORD
polygon* : p.Polygon;
next* : Polygons;
END;
VAR
polygons*: Polygons;
PROCEDURE DrawCoords(f: Views.Frame; l,t, x, y: INTEGER);
VAR xs,ys, r:ARRAY 32 OF CHAR ;
BEGIN
Strings.IntToString(x,xs);
Strings.IntToString(y,ys);
r := "(" + xs + "," + ys + ")";
f.DrawString(l, t, Ports.black, r, Fonts.dir.Default());
END DrawCoords;
PROCEDURE DrawInt(f: Views.Frame; l,t, i: INTEGER);
VAR is:ARRAY 32 OF CHAR ;
BEGIN
Strings.IntToString(i,is);
f.DrawString(l, t, Ports.black, is, Fonts.dir.Default());
END DrawInt;
PROCEDURE DrawVector2D (f: Views.Frame; l,t:INTEGER;vec:v.Vector2);
VAR ex, ey : INTEGER;
BEGIN
ex := l + SHORT(ENTIER(vec[0])) * pointSize;
ey := t - SHORT(ENTIER(vec[1])) * pointSize;
f.DrawLine(l, t, ex, ey, Ports.point, Ports.black);
DrawCoords(f, ex, ey+Ports.point*10, SHORT(ENTIER(vec[0])), SHORT(ENTIER(vec[1])))
END DrawVector2D;
PROCEDURE DrawPoly (f : Views.Frame; l, t : INTEGER; poly : p.Polygon);
VAR ex, ey, i : INTEGER;
path : POINTER TO ARRAY OF Ports.Point;
BEGIN
NEW(path,poly.Length());
FOR i:= 0 TO LEN(path) - 1 DO
path[i].x := l + SHORT(ENTIER(poly.vector[0] * pointSize)) ;
path[i].y := t - SHORT(ENTIER(poly.vector[1] * pointSize)) ;
poly := poly.next;
END;
f.DrawPath(path, LEN(path), Ports.point, Ports.black, Ports.closedPoly);
END DrawPoly;
PROCEDURE ReadVector(s: TextMappers.Scanner; to:INTEGER; OUT vec: v.Vector2):BOOLEAN;
BEGIN
WHILE (s.type # TextMappers.int) & (s.type # TextMappers.real) & (s.start < to) DO s.Scan END;
IF s.type = TextMappers.int THEN vec[0] := s.int;
ELSIF s.type = TextMappers.real THEN vec[0] := s.real;
ELSE RETURN FALSE;;
END;
s.Scan;
WHILE (s.type # TextMappers.int) & (s.type # TextMappers.real) & (s.start < to) DO s.Scan END;
IF s.type = TextMappers.int THEN vec[1] := s.int;
ELSIF s.type = TextMappers.real THEN vec[1] := s.real;
ELSE RETURN FALSE;
END;
RETURN TRUE;
END ReadVector;
PROCEDURE ReadPolyFromSelection*(): p.Polygon;
(** use TextCmds.SelectionGuard as guard for this command **)
VAR c: TextControllers.Controller; from, to, schars, chars, views: INTEGER;
s: TextMappers.Scanner;
result, current : p.Polygon;
vec : v.Vector2;
BEGIN
c := TextControllers.Focus();
IF (c # NIL) & c.HasSelection() THEN
c.GetSelection(from, to); (* get selection range; from < to *)
s.ConnectTo(c.text); (* connect scanner to this text model *)
s.SetPos(from); (* set the reader to beginning of selection *)
WHILE ReadVector(s,to, vec) DO
IF result = NIL THEN
result := p.CreatePolygon(vec);
current := result;
ELSE
current.next := p.CreatePolygon(vec);
current := current.next;
END;
END;
END;
RETURN result;
END ReadPolyFromSelection;
PROCEDURE DrawGrid2D (f: Views.Frame; l,t:INTEGER);
CONST maxTicks = 20;
CONST tickSize = pointSize * 1;
CONST padding = tickSize * maxTicks;
VAR i: INTEGER;
BEGIN
FOR i := -maxTicks TO maxTicks DO
IF i # 0 THEN
f.DrawLine(l + i * tickSize, t - padding, l + i * tickSize , t + padding, Ports.point,
Ports.grey12);
f.DrawLine(l -padding, t + i * tickSize, l + padding , t + i * tickSize, Ports.point,
Ports.grey12);
END;
DrawInt(f, l + i * tickSize, t+Ports.point*10, i);
IF (i MOD 5 = 0) & (i # 0) THEN
DrawInt(f, l +Ports.point*5, t + i * tickSize +Ports.point*5, - i);
END;
END;
f.DrawLine(l, t - padding, l , t + padding, Ports.point*2, Ports.black);
f.DrawLine(l -padding, t , l + padding , t , Ports.point*2, Ports.black);
END DrawGrid2D;
PROCEDURE (view: View) Restore (f: Views.Frame; l, t, r, b: INTEGER);
VAR xc,yc,w,h: INTEGER; ps : Polygons;
BEGIN
view.context.GetSize(w,h);
xc := w DIV 2;
yc := h DIV 2;
DrawGrid2D(f, xc, yc);
(*DrawVector2D(f, xc, yc, v.Add(v.Vector2(1,0), v.Vector2(2,5)));*)
ps := polygons;
WHILE ps # NIL DO
DrawPoly(f, xc, yc, ps.polygon);
ps := ps.next;
END;
(*f.DrawRect(l, t, r, b, Ports.fill, Ports.red)*)
END Restore;
PROCEDURE Deposit*;
VAR v: View;
BEGIN
NEW(v); Views.Deposit(v)
END Deposit;
PROCEDURE (v: View) HandlePropMsg (VAR msg: Properties.Message);
BEGIN
WITH msg: Properties.SizePref DO
IF (msg.w = Views.undefined) OR (msg.h = Views.undefined) THEN
msg.w := 200 * Ports.mm; msg.h := 200 * Ports.mm
END
ELSE (* ignore other messages *)
END
END HandlePropMsg;
PROCEDURE Print(vec:v.Vector2);
VAR i: INTEGER;
BEGIN
StdLog.Char('(');
FOR i := 0 TO LEN(vec) - 1
DO StdLog.Real(vec[i]);END;
StdLog.Char(')');
END Print;
PROCEDURE Read*();
BEGIN
NEW(polygons);
polygons.polygon := ReadPolyFromSelection();
END Read;
PROCEDURE Dynos100*();
VAR x,y:INTEGER;
original : p.Polygon;
res : Polygons;
vec : v.Vector2;
BEGIN
original := polygons.polygon;
IF original = NIL THEN RETURN END;
FOR x := -5 TO 5 DO
FOR y := -5 TO 5 DO
v.Init2(x,y,vec);
IF res = NIL THEN
NEW(res);
polygons := res;
ELSE
NEW(res.next);
res := res.next;
END;
res.polygon := original.Scale(0.1);
res.polygon := res.polygon.AddVector(vec);
END;
END;
END Dynos100;
PROCEDURE Test*();
VAR c:p.Polygon;ps : Polygons;
BEGIN
ps := polygons;
WHILE ps # NIL DO
c:=ps.polygon;
WHILE c # NIL DO
Print(c.vector);
c := c.next;
END;
StdLog.Ln;
ps := ps.next;
END;
END Test;
BEGIN
END LinalgGraph.
"LinalgGraph.Deposit; StdCmds.Open"
LinalgGraph.Read
LinalgGraph.Test
LinalgGraph.Dynos100
(6,4), (3,1), (1,2), (-1,5), (-2,5), (-3,4), (-4,4),
(-5,3), (-5,2), (-2,2), (-5,1), (-4,0), (-2,1), (-1,0), (0,-3),
(-1,-4), (1,-4), (2,-3), (1,-2), (3,-1), (5,1)
MODULE LinalgPolygon;
IMPORT v :=LinalgVector ;
TYPE Polygon* = POINTER TO RECORD
vector* : v.Vector2;
next* : Polygon;
END;
PROCEDURE (p: Polygon) Length*(): INTEGER, NEW;
BEGIN
IF p.next # NIL THEN
RETURN 1 + p.next.Length();
ELSE
RETURN 1;
END;
END Length;
PROCEDURE CreatePolygon*(vec:v.Vector2): Polygon;
VAR p : Polygon;
BEGIN
NEW(p);
p.vector := vec;
RETURN p;
END CreatePolygon;
PROCEDURE (p: Polygon) Join*(vec:v.Vector2): Polygon, NEW;
BEGIN
p.next:= CreatePolygon(vec);
RETURN p.next;
END Join;
PROCEDURE (p: Polygon) Ignore*(), NEW;
BEGIN
END Ignore;
PROCEDURE (p : Polygon) AddVector*(vec:v.Vector2) :Polygon, NEW;
VAR result : Polygon;
BEGIN
NEW(result);
v.Add(p.vector, vec, result.vector);
IF p.next # NIL THEN
result.next := p.next.AddVector(vec);
END;
RETURN result;
END AddVector;
PROCEDURE TestAddVector*();
VAR x,y : v.Vector2;p,p2:Polygon;
BEGIN
v.Init2(1,2, x);
v.Init2(2,3, y);
p := CreatePolygon(x);
p.Join(x).Ignore();
p2 := p.AddVector(y);
ASSERT(p2.Length() = 2);
ASSERT(p2.vector[0] = 3.0);
ASSERT(p2.vector[1] = 5.0);
ASSERT(p2.next.vector[0] = 3.0);
ASSERT(p2.next.vector[1] = 5.0);
END TestAddVector;
PROCEDURE (p : Polygon) Scale*(r:REAL) :Polygon, NEW;
VAR result : Polygon;
BEGIN
NEW(result);
v.Scale(p.vector, r, result.vector);
IF p.next # NIL THEN
result.next := p.next.Scale(r);
END;
RETURN result;
END Scale;
PROCEDURE TestScale*();
VAR x: v.Vector2;p,p2:Polygon;
BEGIN
v.Init2(1,2, x);
p := CreatePolygon(x);
p.Join(x).Ignore();
p2 := p.Scale(0.1);
ASSERT(p2.Length() = 2);
ASSERT(p2.vector[0] = 0.1);
ASSERT(p2.vector[1] = 0.2);
ASSERT(p2.next.vector[0] = 0.1);
ASSERT(p2.next.vector[1] = 0.2);
END TestScale;
END LinalgPolygon.
LinalgPolygon.TestAddVector
LinalgPolygon.TestScale
MODULE LinalgVector;
IMPORT Math;
TYPE Vector2* = ARRAY 2 OF REAL;
Vector3 = ARRAY 3 OF REAL;
VectorM = POINTER TO ARRAY OF REAL;
PROCEDURE Init2*(x,y:REAL; OUT v : Vector2);
BEGIN
v[0] := x;
v[1] := y;
END Init2;
PROCEDURE VectorFromArray*(x: ARRAY OF REAL):VectorM;
VAR v: VectorM;i:INTEGER;
BEGIN
NEW(v, LEN(x));
FOR i := 0 TO LEN(x) - 1 DO
v[i] := x[i];
END;
RETURN v;
END VectorFromArray;
PROCEDURE Add*(x,y:Vector2;OUT v:Vector2);
VAR i:INTEGER;
BEGIN
FOR i := 0 TO LEN(x) - 1 DO v[i] := x[i] + y[i]; END;
END Add;
PROCEDURE TestAdd*();
VAR x,y,z : Vector2;
BEGIN
Init2(1,2, x);
Init2(2,3, y);
Add(x,y,z);
ASSERT(z[0] = 3.0);
ASSERT(z[1] = 5.0);
END TestAdd;
PROCEDURE Scale*(x:Vector2; scalar:REAL;OUT v:Vector2);
VAR i:INTEGER;
BEGIN
FOR i := 0 TO LEN(x) - 1 DO
v[i] := x[i] * scalar;
END;
END Scale;
PROCEDURE TestScale*();
VAR x,y : Vector2;
BEGIN
Init2(1,2, x);
Scale(x,0.1, y);
ASSERT(y[0] = 0.1);
ASSERT(y[1] = 0.2);
END TestScale;
PROCEDURE Sum*(xs:ARRAY OF Vector2; OUT v:Vector2);
VAR i, j:INTEGER;
BEGIN
FOR i := 0 TO LEN(xs) - 1 DO
FOR j := 0 TO LEN(xs[0]) - 1 DO
v[i] := v[i] + xs[j][i];
END;
END;
END Sum;
PROCEDURE Sub*(x,y:Vector2; OUT v:Vector2);
VAR i:INTEGER;
BEGIN
FOR i := 0 TO LEN(x) - 1 DO
v[i] := x[i] - y[i];
END;
END Sub;
PROCEDURE Length*(x: Vector2):REAL;
VAR len : REAL; i: INTEGER;
BEGIN
len:=0;
FOR i := 0 TO LEN(x) - 1 DO
len := len + x[i] * x[i]
END;
RETURN Math.Sqrt(len);
END Length;
END LinalgVector.
LinalgVector.TestAdd
LinalgVector.TestScale
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment