Page 1 of 1

ChatGPT: (mind = blown)

PostPosted: Wed Mar 08, 2023 2:00 pm
by Mark F. Madura
FWIW,

I experimented with ChatGPT to see if it could return a Delphi routine for a Torus Knot. Here's my question and response. I've knot :wink: tested it yet but the potential is mind blowing.
DelphiTorusKnot.jpg
Delphi Torus Knot

MFM

Re: ChatGPT: (mind = blown)

PostPosted: Wed Mar 08, 2023 3:15 pm
by dhs
Couldn't resist doing a quick test (my code pasted below). Not certain what the exact function of the p&q parameters, but testing with various values simply resulted in a number of overlapping vertical elipses parallel to the X axis ...

Code: Select alllibrary Knot;

{$E dmx}  // dmx is the extension for DCAL Dll's
{$R *.res}

uses
 // System.Math, Winapi.Windows,
  UConstants in '..\..\..\d4d_headerfiles\14\UConstants.pas',
  UDCLibrary in '..\..\..\d4d_headerfiles\14\UDCLibrary.pas',
  UInterfaces in '..\..\..\d4d_headerfiles\14\UInterfaces.pas',
  UInterfacesRecords in '..\..\..\d4d_headerfiles\14\UInterfacesRecords.pas',
  URecords in '..\..\..\d4d_headerfiles\14\URecords.pas',
  UVariables in '..\..\..\d4d_headerfiles\14\UVariables.pas';

type
  KnotL = record
    state: asint;
    p, q, steps : integer;
    radius : double;
    case byte of
      0: (geti: getintArg);
      1: (getd: getdisArg);
  end;

  PKnotL = ^KnotL;

function TorusKnot (p, q : asint; radius : double; steps : asint) : TArray<point>;
var
  i, j : integer;
  t, phi : double;
begin
  SetLength (result, steps);
  phi := 2*Pi*q/p;
  for i := 0 to steps-1 do begin
    t := 2*Pi*i/steps;
    Result[i].x := (radius * Cos(p*t) + 2*Cos(q*t)) * Cos(phi);
    Result[i].y := (radius * Cos(p*t) + 2*Cos(q*t)) * Sin(phi);
    Result[i].z := radius * Sin(p*t);
  end;
end;

function knot_main(act: action; pl, pargs: Pointer): wantType;
var
  retval: asint;
  l: PKnotL;
  knotpoints : TArray<point>;
  i: integer;
  ent : entity;
begin
  l := PKnotL(pl);

  if act = aagain then begin
    case l^.state of
      1: l^.state := 2;
      2: l^.state := 3;
      3: l^.state := 4;
      4: begin
        knotpoints := TorusKnot (l^.p, l^.q, l^.radius, l^.steps);
        for i := 0 to l^.steps-1 do begin
          ent_init (ent, entln3);
          ent.ln3pt1 := knotpoints[i];
          ent.ln3pt2 := knotpoints[(i+1) mod l^.steps];
          ent_add (ent);
          ent_draw (ent, drmode_white);
        end;
        l^.state := 0;
      end;
    else l^.state := 0;
    end; { Case }
  end;

  if act = Afirst then begin
    l^.state := 1;
  end

  else if act = AlSize then begin
    SetLocalSize(sizeof(l^));
  end;

  if act <> AlSize then begin { Action section - Invoke the Dispatcher }
    case l^.state of
      1: begin
          wrtmsg ('p:');
          getint(l^.p, l.geti, retval);
         end;
      2: begin
          wrtmsg ('q:');
          getint(l^.q, l.geti, retval);
         end;
      3: begin
          wrtmsg ('radius:');
          getdis(l^.radius, l.getd, retval);
         end;
      4: begin
          wrtmsg ('steps:');
          getint(l^.steps, l.geti, retval);
         end;
     else retval := XDone; // Don't go back to Aagain
    end; { Case }
  end; { Action section }
  Result := retval;
end; { knot_main }

function Main(dcalstate: asint; act: action; pl, pargs: Pointer): wantType; stdcall;
begin
  case dcalstate of
    XDcalStateBegin: Result := knot_main(act, pl, pargs);
  else Result := XDone; { Necessary }
  end;
end;

exports
  Main; { This is the entry function that will be called by DataCAD.
  All DCAL Dlls will have this function. }

begin

end.

Re: ChatGPT: (mind = blown)

PostPosted: Wed Mar 08, 2023 4:18 pm
by Mark F. Madura
Hi David,

I had to ask again and got an updated result.

Code: Select alltype
  TPoint3D = record
    X, Y, Z: Double;
  end;

function TorusKnotPoints(r1, r2: Double; numPoints, p, q: Integer): TArray<TPoint3D>;
var
  t, theta: Double;
  i: Integer;
begin
  SetLength(Result, numPoints);
  for i := 0 to numPoints-1 do
  begin
    t := 2 * Pi * i / numPoints;
    theta := t * p;
    Result[i].X := (r1 + r2 * Cos(q * theta)) * Cos(theta);
    Result[i].Y := (r1 + r2 * Cos(q * theta)) * Sin(theta);
    Result[i].Z := r2 * Sin(q * theta);
  end;
end;

procedure GeneratePoints();
var
  i: Integer;
  Knot: TArray<TPoint3D>

begin
  for i := 0 to Length(Knot) - 1 do begin

    pt.x := Knot[i].X;
    pt.y := Knot[i].Y;
    pt.z := Knot[i].Z;

    ent_init(ent, entmrk);
    ent.mrkpnt := pt;
    ent.Non_Printing := 0; // Make points printable
    ent_add(ent);          // current color, line type, etc.
    //ent.color := RandomRange(1, 255);
    ent.mrktyp := 1; // RandomRange(1, 8); { 1-square, 2-'x', 3-diamond, 4-dot, ... }
    // ent.mrksiz := RandomRange(16, 64); { size in pixels }
    ent_update(ent);       // update entity properties
    ent_draw(ent, drmode_white); { draw entity on the screen }
  end;
end;


The first result was incomplete.

Here's the Knot of points around the Torus.
TorusKnot.jpg
Torus Knot
TorusKnot.jpg (103.08 KiB) Viewed 25801 times

Re: ChatGPT: (mind = blown)

PostPosted: Wed Mar 08, 2023 4:55 pm
by dhs
Thanks Mark,
I'm getting more interesting results now. My test produces 3d lines so I tried running my Extrude macro over one of the results. I was aware that the macro does not connect chains of 3d lines (simply extrudes each individual line with square ends as illustrated below) and it has always been my intention to add true 3D chaining at some stage ... maybe this will inspire me to get that bit of work done.
knot.png
knot.png (27.05 KiB) Viewed 25792 times

Re: ChatGPT: (mind = blown)

PostPosted: Thu Mar 09, 2023 12:04 pm
by Mark F. Madura
Hi David,

That would be great. Here's a knot using a cyclic contour. I can sweep it, but I'm limited to 36 nodes.

TorusKnotSweep.jpg
Torus Knot Sweep
TorusKnotSweep.jpg (91.46 KiB) Viewed 25778 times


MFM