javascript for drawing a profile  SOLVED

Forum for the PDF-XChange Editor - Free and Licensed Versions

Moderators: PDF-XChange Support, Daniel - PDF-XChange, Chris - PDF-XChange, Sean - PDF-XChange, Paul - PDF-XChange, Vasyl - PDF-XChange, Ivan - Tracker Software, Stefan - PDF-XChange

Jajabings63
User
Posts: 25
Joined: Mon Feb 26, 2024 10:07 am

javascript for drawing a profile

Post by Jajabings63 »

I would like to develop a script that draws a steel profile with height=h, width=b, flange thickness=t, web thickness=s and fillet radius=r. Unfortunately, my scripts do not work because I am probably not using the exact syntax of the PDF-Xchange API. Can anyone help me?
Thank you all.

Code: Select all

// JavaScript Document
// Funktion zum Zeichnen eines Viertelkreises
function drawQuarterCircle(center, radius, clockwise) {
    var startAngle = clockwise ? 0 : 90;
    var endAngle = clockwise ? 90 : 0;
    var circle = this.addAnnot({
        page: this.pageNum,
        type: "Circle",
        rect: [center[0] - radius, center[1] - radius, center[0] + radius, center[1] + radius],
        lineWidth: 2,
        startAngle: startAngle,
        endAngle: endAngle
    });
    console.println("Viertelkreis gezeichnet um Punkt (" + center[0] + ", " + center[1] + ") mit Radius " + radius + " (Uhrzeigersinn: " + clockwise + ")");
    console.println("Anmerkung hinzugefügt: " + circle);
    return circle;
}

// Funktion zum Zeichnen des Stahlprofils
function drawSteelProfile(h, b, t, s, r) {
    console.println("Funktion drawSteelProfile aufgerufen.");
    console.println("Aktuelle Seite: " + this.pageNum);
    console.println("Profilhöhe: " + h);
    console.println("Flanschbreite: " + b);
    console.println("Flanschdicke: " + t);
    console.println("Stegdicke: " + s);
    console.println("Ausrundungsradius: " + r);

    // Array für die Punkte entlang des Profils
    var points = [];

    // Punkte am Untergurt
    console.println("Punkte am Untergurt:");
    points.push([0, 0]); // Punkt 1
    console.println("Punkt 1: " + points[0]);
    points.push([b, 0]); // Punkt 2
    console.println("Punkt 2: " + points[1]);
    points.push([b, t]); // Punkt 3
    console.println("Punkt 3: " + points[2]);
    points.push([b/2+s/2+r, t]); // Punkt 4
    console.println("Punkt 4: " + points[3]);
    points.push([b/2+s/2, t+r]); // Punkt 5
    console.println("Punkt 5: " + points[4]);

    // Mittelpunkte für den Ausrundungsradius
    console.println("Mittelpunkte für den Ausrundungsradius:");
    var midpoint14_15 = [b/2-s/2-r, t+r]; // Mittelpunkt zwischen Punkt 14 und 15
    console.println("Mittelpunkt14_15: " + midpoint14_15);
    var midpoint4_5 = [b/2+s/2+r, t+r]; // Mittelpunkt zwischen Punkt 4 und 5
    console.println("Mittelpunkt4_5: " + midpoint4_5);

    // Viertelkreise zwischen den Punkten
    console.println("Viertelkreise zwischen den Punkten:");
    var quarterCircle14_15 = drawQuarterCircle(midpoint14_15, r, true);
    var quarterCircle4_5 = drawQuarterCircle(midpoint4_5, r, false);
    // Punkte am Obergurt
    console.println("Punkte am Obergurt:");
    points.push([b/2+s/2, h-t-r]); // Punkt 6
    console.println("Punkt 6: " + points[5]);
    points.push([b/2+s/2+r, h-t]); // Punkt 7
    console.println("Punkt 7: " + points[6]);
    points.push([b, h-t]); // Punkt 8
    console.println("Punkt 8: " + points[7]);
    points.push([b, h]); // Punkt 9
    console.println("Punkt 9: " + points[8]);
    points.push([0, h]); // Punkt 10
    console.println("Punkt 10: " + points[9]);
    points.push([0, h-t]); // Punkt 11
    console.println("Punkt 11: " + points[10]);
    points.push([b/2-s/2-r, h-t]); // Punkt 12
    console.println("Punkt 12: " + points[11]);
    points.push([b/2-s/2, h-t-r]); // Punkt 13
    console.println("Punkt 13: " + points[12]);

    // Viertelkreise zwischen den Punkten
    console.println("Viertelkreise am Obergurt:");
    var midpoint12_13 = [b/2-s/2-r, h-t-r]; // Mittelpunkt zwischen Punkt 12 und 13
    console.println("Mittelpunkt12_13: " + midpoint12_13);
    var midpoint6_7 = [b/2+s/2+r, h-t-r]; // Mittelpunkt zwischen Punkt 6 und 7
    console.println("Mittelpunkt6_7: " + midpoint6_7);
    var quarterCircle12_13 = drawQuarterCircle(midpoint12_13, r, true);
    var quarterCircle6_7 = drawQuarterCircle(midpoint6_7, r, false);

    // Punkte am Untergurt
    console.println("Punkte am Untergurt (vollständig):");
    points.push([b/2-s/2, t+r]); // Punkt 14
    console.println("Punkt 14: " + points[13]);
    points.push([b/2-s/2-r, t]); // Punkt 15
    console.println("Punkt 15: " + points[14]);
    points.push([0, t]); // Punkt 16
    console.println("Punkt 16: " + points[15]);

    // Punkte für die Linienverbindungen
    console.println("Punkte für die Linienverbindungen:");
    points.push([0, 0]); // Punkt 17
    console.println("Punkt 17: " + points[16]);

    // Iteration über die Punkte, um die Linien zu zeichnen und als Anmerkungen einzufügen
    console.println("Linien zeichnen:");
    for (var i = 0; i < points.length - 1; i++) {
        var from = points[i];
        var to = points[i + 1];
        var line = this.addAnnot({
            page: this.pageNum,
            type: "Line",
            rect: [from[0], from[1], to[0], to[1]],
            lineWidth: 2
        });
        console.println("Linie gezeichnet von (" + from[0] + ", " + from[1] + ") nach (" + to[0] + ", " + to[1] + ")");
        console.println("Anmerkung hinzugefügt: " + line);
    }
}
KD952
User
Posts: 109
Joined: Mon Feb 13, 2023 6:13 am

Re: javascript for drawing a profile

Post by KD952 »

Hello! Jajabings63!

Sorry, I don't have time this month to help you.

Maybe a few hints will help too:
  • Here is the link to the API : https://opensource.adobe.com/dc-acrobat-sdk-docs/library/jsapiref/JS_API_AcroJS.html
  • I don't know of a way to draw half circles. I guess you will have to approximate them with lines.
Kind regards,
Daniel
User avatar
Stefan - PDF-XChange
Site Admin
Posts: 19876
Joined: Mon Jan 12, 2009 8:07 am

Re: javascript for drawing a profile

Post by Stefan - PDF-XChange »

Hello KD952,

Thanks for the help!
Indeed the PDF specification does not really have an annotation object that can be a portion or a circle/ark. There are the Bezier curves that we use e.g. for the pencil tool - but I do not believe there is a way for JS to create such curved lines.

Kind regards,
Stefan
Mathew
User
Posts: 581
Joined: Thu Jun 19, 2014 7:30 pm

Re: javascript for drawing a profile

Post by Mathew »

Hi Jajabings63,

Ooh, this sounds like it could be a really useful tool. Maybe consider using a PolyLine annotation instead of individual lines so that everything stays together as a single object? You can add the series of points as an array to the .vertices property in the form [[x1,y1],[x2,y2],...]

For creating rounded rectangles in this tool viewtopic.php?p=178659#p178659 I used a PolyLine and split the curve into line segments and calculated the coordinates of the curves relative to the corner point. I was in a bit of a hurry, so didn't document the script very well, but you're welcome to reuse code as you need. The function to calculate the arc is, 'r' is the radius in points, nSeg is number of straight line segments:

Code: Select all

// calculate the arc points
function getArcPts( r, nSeg ) {
	let pts=[]; // only need x values because y values are pts[pts.length - i - 1]

	for (let i=0; i<=nSeg; i++) {
		pts[i] = Math.cos(Math.PI/2/nSeg*i)*r;
	}
	return pts;
}
You could loop through these points, and add/subtract from the corner point to find points along the arc near that corner... I'll try to post more if I have time.
Jajabings63
User
Posts: 25
Joined: Mon Feb 26, 2024 10:07 am

Re: javascript for drawing a profile

Post by Jajabings63 »

I finished the script and added a little icon.
Thank You all for your help.
dyn_Profile.zip
You do not have the required permissions to view the files attached to this post.
KD952
User
Posts: 109
Joined: Mon Feb 13, 2023 6:13 am

Re: javascript for drawing a profile

Post by KD952 »

Thank you very much for your work Jajabings63!

Grüße gehen raus nach Deutschland, Österreich oder die Schweiz. :D
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 11058
Joined: Wed Jan 03, 2018 6:52 pm

Re: javascript for drawing a profile

Post by Daniel - PDF-XChange »

Hello,

This looks fantastic, Good work!

Kind regards,
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
Mathew
User
Posts: 581
Joined: Thu Jun 19, 2014 7:30 pm

Re: javascript for drawing a profile  SOLVED

Post by Mathew »

@Jajabings63 thank you for this! I've been fiddling around drawing these shapes by hand for years in markups. Very helpful.

This got me to go down a bit of a rabbit hole though; I hope you don't mind, but I took your script and modified it a bit:
  • I put all the dialogs into a single custom dialog.
  • I changed it to draw using a single polygon instead of lots of individual lines (so I can move it around as one object).
  • I got a bit into finding a way to translate the displayed text (the tool is posted in another forum post) but I included a translation file for English in the file below.
  • Added an option to pick units (mm or inch) - I work in inches.
  • It saves the last inputted information and shows that as the default next time the tool is run.
  • I made my own slightly larger icon.
**EDIT** Updated with the most recent translation function 1ang.js v1.0 and changed the icon slightly:
dyn_Profile_neu v0.4.zip

Previous version: Saved UTF-8 to support extended unicode such as ß. Fixed in 0.3
dyn_Profile_neu v0.3.zip
You do not have the required permissions to view the files attached to this post.
Last edited by Mathew on Tue Jul 30, 2024 5:40 pm, edited 1 time in total.
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 11058
Joined: Wed Jan 03, 2018 6:52 pm

javascript for drawing a profile

Post by Daniel - PDF-XChange »

:)
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
Jajabings63
User
Posts: 25
Joined: Mon Feb 26, 2024 10:07 am

Re: javascript for drawing a profile

Post by Jajabings63 »

Dear community, I have extended the script so that rolled profiles can also be selected and drawn.
I have not done the translation as I have not yet understood the handling of this translation tool.
I hope you all enjoy using it.
You do not have the required permissions to view the files attached to this post.
Mathew
User
Posts: 581
Joined: Thu Jun 19, 2014 7:30 pm

Re: javascript for drawing a profile

Post by Mathew »

Nice! Thanks!
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 11058
Joined: Wed Jan 03, 2018 6:52 pm

javascript for drawing a profile

Post by Daniel - PDF-XChange »

:)
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
User avatar
⚜ Kenny Lemens, P.E. ᵂᴵ
User
Posts: 38
Joined: Thu Jan 23, 2025 4:09 pm

Re: javascript for drawing a profile

Post by ⚜ Kenny Lemens, P.E. ᵂᴵ »

Greetings,

First: this is an amazing Utility, thank you all for the creation and refinement of it!

Second: I am now curious, has anybody attempted to create/generate Section properties off of this shape (e.g., Area, Moment of Inertia, Plastic Modulus, etc.)?

May this be of Good Help;
⚜ Kenny Lemens, P.E. ᵂᴵ
User Plugins: https://is.gd/A9HMPG || PDF-XChange Icons: https://is.gd/Z4GeG8
[Migration] Revu Bluebeam 17 to PDF-XChange Editor: https://is.gd/8Xs1OF
User avatar
Daniel - PDF-XChange
Site Admin
Posts: 11058
Joined: Wed Jan 03, 2018 6:52 pm

Re: javascript for drawing a profile

Post by Daniel - PDF-XChange »

Hello, ⚜ Kenny Lemens, P.E. ᵂᴵ

I'm going to assume from the radio silence on your second question that the answer is likely "no". But I am similarly not sure what exactly it is you are looking for in that area?

"Custom properties" are not really possible in PDF, whether for comments or base content. All properties are defined by the specification, and adding anything which is not clearly defined there is inherently somewhat dangerous.
For example, a property labelled "moment of inertia" would not work, and likely would not be visible to any PDF handler, even if you could force it into something. It may also damage the document simply by existing, depending on how other apps interpret that unexpected data, so I would advise against it in any case.

On the other hand, if you are looking for some reporting function that just assumes some data about the shape, and prints out those details in a DLG window, that may be more possible (though likely exclusive to comments), and should be risk free.

Kind regards,
Dan McIntyre - Support Technician
PDF-XChange Co. LTD

+++++++++++++++++++++++++++++++++++
Our Web site domain and email address has changed as of 26/10/2023.
https://www.pdf-xchange.com
Support@pdf-xchange.com
Mathew
User
Posts: 581
Joined: Thu Jun 19, 2014 7:30 pm

Re: javascript for drawing a profile

Post by Mathew »

⚜ Kenny Lemens, P.E. ᵂᴵ wrote: Tue Feb 11, 2025 5:29 pm I am now curious, has anybody attempted to create/generate Section properties off of this shape (e.g., Area, Moment of Inertia, Plastic Modulus, etc.)?
Kenny,
I've not tried it. I'm assuming you mean something similar to massprop in AutoCAD? That would take a huge amount of googling for me. Thinking out loud: I wonder if any of the AI interfaces could come up with a script to convert an arbitrary polygon into section properties?
-Mathew.
Mathew
User
Posts: 581
Joined: Thu Jun 19, 2014 7:30 pm

Re: javascript for drawing a profile

Post by Mathew »

... less than a minute later: wow (MS copilot) :shock: :
image(1).png

Code: Select all

function polygonProperties(vertices) {
  const n = vertices.length;

  // Helper function to calculate the cross product of two points
  function crossProduct(p1, p2) {
    return p1[0] * p2[1] - p1[1] * p2[0];
  }

  // Calculate the area using the shoelace formula
  let area = 0;
  for (let i = 0; i < n; i++) {
    const p1 = vertices[i];
    const p2 = vertices[(i + 1) % n];
    area += crossProduct(p1, p2);
  }
  area = Math.abs(area) / 2;

  // Calculate the perimeter
  let perimeter = 0;
  for (let i = 0; i < n; i++) {
    const p1 = vertices[i];
    const p2 = vertices[(i + 1) % n];
    perimeter += Math.sqrt((p2[0] - p1[0]) ** 2 + (p2[1] - p1[1]) ** 2);
  }

  // Calculate the centroid
  let centroidX = 0;
  let centroidY = 0;
  for (let i = 0; i < n; i++) {
    const p1 = vertices[i];
    const p2 = vertices[(i + 1) % n];
    const cross = crossProduct(p1, p2);
    centroidX += (p1[0] + p2[0]) * cross;
    centroidY += (p1[1] + p2[1]) * cross;
  }
  const factor = 1 / (6 * area);
  centroidX *= factor;
  centroidY *= factor;

  // Calculate the moments of inertia about the centroid
  let Ixx = 0;
  let Iyy = 0;
  let Ixy = 0;
  for (let i = 0; i < n; i++) {
    const p1 = vertices[i];
    const p2 = vertices[(i + 1) % n];
    const cross = crossProduct(p1, p2);
    const x1 = p1[0] - centroidX;
    const y1 = p1[1] - centroidY;
    const x2 = p2[0] - centroidX;
    const y2 = p2[1] - centroidY;
    Ixx += (y1 * y1 + y1 * y2 + y2 * y2) * cross;
    Iyy += (x1 * x1 + x1 * x2 + x2 * x2) * cross;
    Ixy += (x1 * y1 + x1 * y2 + x2 * y1 + x2 * y2) * cross;
  }
  Ixx = (Math.abs(Ixx) / 12) - area * centroidY * centroidY;
  Iyy = (Math.abs(Iyy) / 12) - area * centroidX * centroidX;
  Ixy = (Math.abs(Ixy) / 24) - area * centroidX * centroidY;

  // Output the results
  return {
    area,
    perimeter,
    centroid: [centroidX, centroidY],
    momentsOfInertia: {
      Ixx,
      Iyy,
      Ixy
    }
  };
}

// Example usage (slightly changed to work with PXE by mathew):
{
const vertices = [[0, 0], [4, 0], [4, 3], [0, 3]];
const properties = polygonProperties(vertices);
console.println(JSON.stringify(properties));
}
//{"area":12,"perimeter":14,"centroid":[2,1.5],"momentsOfInertia":{"Ixx":-18,"Iyy":-32,"Ixy":-36}}
from the tool:
image.png
and I learned a super useful little snippet from this: const p2 = vertices[(i + 1) % n]; gets the next item in the list, or the first if i+1 === n. Genius.
You do not have the required permissions to view the files attached to this post.
User avatar
Stefan - PDF-XChange
Site Admin
Posts: 19876
Joined: Mon Jan 12, 2009 8:07 am

javascript for drawing a profile

Post by Stefan - PDF-XChange »

:)
Mathew
User
Posts: 581
Joined: Thu Jun 19, 2014 7:30 pm

Re: javascript for drawing a profile

Post by Mathew »

BTW this is classic AI:

The easier calculations are correct, but the moment of inertia about the centroid calculations are incorrect. Even for the simple example of a 4x3 rectangle Ixx = 4 * 3^3 / 12 = 9 and Ixx & Iyy should be positive.
User avatar
Stefan - PDF-XChange
Site Admin
Posts: 19876
Joined: Mon Jan 12, 2009 8:07 am

Re: javascript for drawing a profile

Post by Stefan - PDF-XChange »

Hello Mathew,

Yes - one should know that AI will produce 'genuinely sounding' reply, but that reply still needs to be verified and tested.
Happy that you do have the knowledge to do so, and I hope everyone else follows the same methodology!

Kind regards,
Stefan
Mathew
User
Posts: 581
Joined: Thu Jun 19, 2014 7:30 pm

Re: javascript for drawing a profile

Post by Mathew »

Stefan,

A bit like a coworker who happily says they are "done"; but half of what they did was wrong (the part you actually needed help with), so you can't trust anything they do.

And I live in a city with cars driven by AI swarming around every corner... :roll:

- Mathew.
User avatar
Stefan - PDF-XChange
Site Admin
Posts: 19876
Joined: Mon Jan 12, 2009 8:07 am

javascript for drawing a profile

Post by Stefan - PDF-XChange »

:)