The DataCAD Developer Network (DDN) is an online resource for information and support for DCAL® (DataCAD Applications Language) developers as well as anyone interested in creating fonts, toolbars, hatch patterns, or linetypes for use in DataCAD.
#82055 by dhs
Wed Mar 08, 2023 3:15 pm
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.
#82057 by Mark F. Madura
Wed Mar 08, 2023 4:18 pm
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 25414 times
#82059 by dhs
Wed Mar 08, 2023 4:55 pm
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 25405 times
#82064 by Mark F. Madura
Thu Mar 09, 2023 12:04 pm
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 25391 times


MFM

Who is online

Users browsing this forum: No registered users and 15 guests

About DataCAD Forum

The DataCAD Forum is a FREE online community we provide to enhance your experience with DataCAD.

We hope you'll visit often to get answers, share ideas, and interact with other DataCAD users around the world.

DataCAD

Software for Architects Since 1984