• Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
    Dedicated community for Japanese speakers
  • 한국 커뮤니티
    Dedicated community for Korean speakers
Exit
0

What is the direction of the curve points returned by entirePath()? [See description for details]

Explorer ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

The entirePath() of a polygon returned these points. As clarified in a different thread, we have established that the order is leftControlPoint anchorPoint rightControlPoint if there are control points at all. Otherwise it is just the anchor point.

Screen Shot 2015-10-12 at 12.35.48.png

The question I have here is, consider line 3, the control points specified there, do they represent the control points for the Bezier curve between Line 2 point and Line 3 point or a Bezier curve between Line 3 point and Line 4 point?

Thanks!

TOPICS
Scripting

Views

3.7K

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines

correct answers 1 Correct answer

Community Expert , Oct 12, 2015 Oct 12, 2015

Nice link, Trevor, thanks.

So in the earlier example, this shape:

ctx.moveTo(20,20);

ctx.bezierCurveTo(20,100,200,100,200,20);

corresponds with the shape you get in InDesign with this script:

g = app.documents[0].pages[0].graphicLines.add ({strokeWeight: 0.5});

g.paths[0].entirePath =

[

[[20, 20], [20, 20], [20, 100]],

[[200, 100], [200, 20], [200, 20]],

];

The curve has two anchors. First anchor at 20,20; no handle, i.e. the incoming handle is on the anchor. The second point has no outgoing handle.

To t

...

Votes

Translate

Translate
Guru ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

I would think that the left control points go to the left (750,1234) which in your specific case is between 2 and 3 and that the right control points go to the right (757, 1238) which in your case is between 3 and 4.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

But I believe this is a quadratic Bezier curve and there need to be two control points to represent it accurately. How would that be satisfied if what you propose is true?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

I think it's cubic and not quadratic, I once looked into it and seem to remember that's what I found documented.

Time for some googling

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

InDesign's curves and handles essentially work the same way as in FontLab, Fontographer, Illustrator, CorelDraw, etc.

P.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

pkahrel wrote:

InDesign's curves and handles essentially work the same way as in FontLab, Fontographer, Illustrator, CorelDraw, etc.

.. and inside Type 1 PostScript fonts! (But not TTF fonts. Now those are quadratic, not cubic.)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

It's clearer if you present the path as an array of arrays (values rounded here):

[

[519,1135],

[613,1135],

[[647,1169],[750,1234],[757,1238]],

[782,1254],

[1536,2048]

]

The third line indicates that the anchor point is at [750,1234] and that the anchor has two handles. When you select an anchor with the direct selection tool you see any handles. The anchor point in line 3 has two handles: the incoming one ('leftDirection') is [647,1169], the outgoing one ('rightDirection') is [757, 1238]. The values are the coordinates of the handles. When you select a handle, the Transform panel shows the coordinates of the anchor, not the handle. (Only when you press a handle and you keep the mouse button down do you see the handle's coordinates, but very briefly.) But you can see a handle's coordinates in the Info panel, see the screenshot.

handles.png

The selected anchor is at 186,400, the outgoing ('rightDirection') handle is at 220,400 (couldn't get the mouse pointer exactly on the spot). The path of this curve can be represented in several ways:

[

[[134, 500], [134, 457], [134, 420]],

[[150, 400], [186, 400], [220, 400]],

[[230, 420], [230, 436], [230, 457]],

]

or

[

    [leftDirection = [134, 500],

    anchor = [134, 457],

    rightDirection = [134, 420]

    ],

    [leftDirection = [150, 400],

    anchor = [186, 400],

    rightDirection = [220, 400]

    ],

    [leftDirection = [230, 420],

    anchor = [230, 436],

    rightDirection = [230, 457]

    ],

];

Peter

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

Thanks a ton for this comprehensive explanation!

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

I have one more question. So I understand, the Bezier between two anchor points a and b can be drawn using the leftControl of b and rightControl of a. But according to the screenshot I posted above, it is not possible as there is no other anchor point with controlPoints so how would I draw a Bezier then?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

Let's sort out some terminology: a Bézier curve is the whole curve. What you call 'control points' are usually called 'handles'. Those handles are used to change the shape of the curve. How exactly the shape is changed when you drag a handle depends on the type of anchor: smooth, symmetrical, etc.

If you have two anchors a and b, the shape of the curve connection a and b can be changed by dragging the outgoing handle of a and/or the incoming handle of b (assuming that you started at a).

To place an anchor with handles, choose the pen tool, click somewhere, keep the mouse button down, and drag somewhere. You'll see the handles appear. If you've not worked with Bézier before it can be a bit of a challenge but it's not really very difficult. Some practice will make things clear. Look into point conversion (Object > Convert point) and the Convert Direction Tool in the Tools menu. Doodle around and draw and change lots of curves!

P.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

I thought that every anchor point was connected by Bezier curves and using the control points I could draw a curve in HTML too. What do I do if I wish to do that?

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

> I thought that every anchor point was connected by Bezier curves . . .

Yes, you're right about that.

> . . . and using the control points I could draw a curve in HTML too. What do I do if I wish to do that?

In HTML? I haven't a clue.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

So to draw a Bezier curve between two points we need the two points between which we wish to draw a curve and two control points. So considering I have the information supplied by InDesign, how would that translate into the the format I require, that is basically my query.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

Not so much an indesign question but you can mess around with HTML canvas bezierCurveTo() Method and google bezier curve html5 demo

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

This is a nice link https://developer.mozilla.org/en-US/docs/Web/API/Canvas_API/Tutorial/Drawing_shapes

The below is pasted from there

Cubic Bezier curves

This example draws a heart using cubic Bézier curves.

function draw() {

  var canvas = document.getElementById('canvas');

  if (canvas.getContext){

    var ctx = canvas.getContext('2d');

    // Quadratric curves example

    var path = new Path2D();

    path.moveTo(75,40);

    path.bezierCurveTo(75,37,70,25,50,25);

    path.bezierCurveTo(20,25,20,62.5,20,62.5);

    path.bezierCurveTo(20,80,40,102,75,120);

    path.bezierCurveTo(110,102,130,80,130,62.5);

    path.bezierCurveTo(130,62.5,130,25,100,25);

    path.bezierCurveTo(85,25,75,37,75,40);

    ctx.fill(path);

  }

}

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

Nice link, Trevor, thanks.

So in the earlier example, this shape:

ctx.moveTo(20,20);

ctx.bezierCurveTo(20,100,200,100,200,20);

corresponds with the shape you get in InDesign with this script:

g = app.documents[0].pages[0].graphicLines.add ({strokeWeight: 0.5});

g.paths[0].entirePath =

[

[[20, 20], [20, 20], [20, 100]],

[[200, 100], [200, 20], [200, 20]],

];

The curve has two anchors. First anchor at 20,20; no handle, i.e. the incoming handle is on the anchor. The second point has no outgoing handle.

To translate InDesign's path to HTML, do a moveTo to the path's first anchor (myCurve.paths[0].pathPoints[0].anchor).

From there you can work out how to proceed.

P.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

Hi all,

First, InDesign uses cubic Bezier curves.

And now, here is the best reference ever about dealing with Bezier curves:

A Primer on Bézier Curves

@+,

Marc

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

Marc Autret wrote:

And now, here is the best reference ever about dealing with Bezier curves:

A Primer on Bézier Curves

Wow! Now that is comprehensive!

I've bookmarked that page to read when I have the mental capacity to digest some of it...

Thanks!

Harbs

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Explorer ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

This is exactly what I wanted! Thanks a lot!

Rishabh K

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

The easiest way to draw this stuff in HTML is using EaselJS.

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

HI Marc and all,

I made a script earlier in the year and read at least some that link then, it was a bit difficult to apply in practice in Illustrator or InDesign.

I needed to as per UI entry draw templates with arches at their ends using bezier curves.  For the simple 1/4 circles rounded corners I used an approximation of something like .55 for the right handle and .45 for the left.

Below is a snippet of part of the script (it was for Illustrator but the principles are the same for ID)

const kLeft = r * 0.44771575927734444444, // constant for leftDirection handle for a 90 degree arc

      kRight = r * 0.55228508843315972222; // constant for rightDirection handle for a 90 degree arc

var c, l, arcPaths, pathPoints;

top = (top == true || top == "top") ? "top" : "bottom";

arcPaths = {

    top : { // top path starting from top right

            anchors: [[x, y], [x - r, y - r]],

            rightDirections: [[x, y], [x - r, y - kLeft]],

            leftDirections: [[x - kRight, y], [x - r, y - r]],

            pointTypes: [PointType.CORNER, PointType.CORNER]

        },

    bottom: { // bottom path starting from top left

            anchors: [[x, y], [x + r, y - r]],

            rightDirections: [[x, y], [x + kLeft, y - r]],

            leftDirections: [[x, y - kRight], [x + r, y - r]],

            pointTypes: [PointType.CORNER, PointType.CORNER]

        }

};

The above would produce the paths and handles which I pushed into arrays to produce the shapes.

That was the easy bit.  The harder bit was that I needed to adds arches of a given radius and width / sagitta.

I wanted to do it mathematically but in the end took the path that I think the OP is taking of using ID or Ai as a crutch to do the math, so I got Ai to draw a circle and a correctly placed rectangle, excluded the rectangle from the circle copied the path of the resulting arc, removed the arc and added the path to the shapes entire path array.

To draw a circle one would use 4 1/4 circles that would be easy enough, to draw an ellipse presumably one would average out the handles in some form of proportion to the translation or the ellipses anchor points from the circle anchor points.  I haven't experimented to get it to work.

What I wanted to do was to make a generic function for segments of ellipses, of height h and width w starting from and a and ending at b.

I know from you sin script tat you read up on the topic. Do you know how to go about it?

Regards

Trevor

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guide ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

Hi Trevor,

I didn't work specifically on ellipses (so far) but I suppose all could be done by just scaling data from basic circle path points. So the main question is about managing circles (and circle arcs) in terms of cubic Bezier curves.

As we already know a Bezier curve cannot perfectly match an exact circle but there are decent approximations (InDesign native circle routine is not very good, by the way). A good read on this issue is: Approximate a circle with cubic Bézier curves (There are also technical details in Drawing Sine Waves in InDesign, although this is a subsidiary topic.)

There are great libraries to study Bezier art in depth. For JavaScript dev I specially recommand Paper.js (many interesting snippets here). And at a higher level (C++) we have of course Inkscape's source code: https://inkscape.org/en/download/source/

Using DOM commands (Pathfinder operations etc.) remains the easier solution anyway… as long as you do not question performances.

Now, going back to your question, give us more detail on what your routine is exactly supposed to do in terms of input/output, then maybe I could bring a starting point.

@+

Marc

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

‌Trevor, there is a very nice PDF floating around on the web which explains in detail the differences between bezier curves and circle segments. But (looking at your magic values) perhaps you've already seen it?

(As a note to others: mathematically you can prove that you cannot draw circles - or ellipses - using bezier curves only, although you can approximate them. Technically, neither InDesign's nor Illustrator's circles are, in fact, actual circles.)

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 12, 2015 Oct 12, 2015

Copy link to clipboard

Copied

Hi Marc and Jongware

Thanks for your reply.

I'll get back tomorrow afternoon.

Trevor

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Guru ,
Oct 13, 2015 Oct 13, 2015

Copy link to clipboard

Copied

Ok, the afternoon came and went.

I did see a lot of sources on the topic but didn't understand how to apply the theory and the terms used in them to practical ID, AI scripting terms.

I am using the terms circles, ellipses etc. as what the look like and what most "normal" people would call them even though I fully understand that they are approximations.  I did see in one of the sources (no idea which) that a better value can be given instead of the standard .552... that is used.  The numbers that I used I think I got by looking at the paths that Ai was producing.  The numbers didn't produce a fixed constant a bigger "circle" produced a different number than a smaller one.

I only noticed now that I didn't need to use 2 numbers .522... and .447... as the .447... is 1 - .52222

I looked today at the Paper.js in particular the function that starts at line 4474 of the paper-core.js file.  Which I shall paste below.

It helps a very lot in understanding things.  Now that from this post we know the conversion from extended script to and from the html "ctx.bezierCurveTo()" it opens up the topic tremendously.

_draw: function(ctx, param, strokeMatrix) {

var style = this._style,

    hasFill = style.hasFill(),

    hasStroke = style.hasStroke(),

    dontPaint = param.dontFinish || param.clip,

    untransformed = !strokeMatrix;

if (hasFill || hasStroke || dontPaint) {

    var type = this._type,

        radius = this._radius,

        isCircle = type === 'circle';

    if (!param.dontStart)

        ctx.beginPath();

    if (untransformed && isCircle) {

        ctx.arc(0, 0, radius, 0, Math.PI * 2, true);

    } else {

        var rx = isCircle ? radius : radius.width,

            ry = isCircle ? radius : radius.height,

            size = this._size,

            width = size.width,

            height = size.height;

        if (untransformed && type === 'rectangle' && rx === 0 && ry === 0) {

            ctx.rect(-width / 2, -height / 2, width, height);

        } else {

            var x = width / 2,

                y = height / 2,

                kappa = 1 - 0.5522847498307936,

                cx = rx * kappa,

                cy = ry * kappa,

                c = [

                    -x, -y + ry,

                    -x, -y + cy,

                    -x + cx, -y,

                    -x + rx, -y,

                    x - rx, -y,

                    x - cx, -y,

                    x, -y + cy,

                    x, -y + ry,

                    x, y - ry,

                    x, y - cy,

                    x - cx, y,

                    x - rx, y,

                    -x + rx, y,

                    -x + cx, y,

                    -x, y - cy,

                    -x, y - ry

                ];

            if (strokeMatrix)

                strokeMatrix.transform(c, c, 32);

            ctx.moveTo(c[0], c[1]);

            ctx.bezierCurveTo(c[2], c[3], c[4], c[5], c[6], c[7]);

            if (x !== rx)

                ctx.lineTo(c[8], c[9]);

            ctx.bezierCurveTo(c[10], c[11], c[12], c[13], c[14], c[15]);

            if (y !== ry)

                ctx.lineTo(c[16], c[17]);

            ctx.bezierCurveTo(c[18], c[19], c[20], c[21], c[22], c[23]);

            if (x !== rx)

                ctx.lineTo(c[24], c[25]);

            ctx.bezierCurveTo(c[26], c[27], c[28], c[29], c[30], c[31]);

        }

    }

    ctx.closePath();

}

From this it should be pretty simple to parse in the jsx.  With this we can draw an ellipse, or a 1/4, 1/2 and 3/4 ellipse using 1, 2, 3 or 4 bezier curves.

This is really all I need, but what I would like is to be able to start and end at any point in the ellipse.

Given H, W, and start and end angles S and E how would I calculate the black bezier curve on the right side of the screenshot?

Screen Shot 2015-10-14 at 00.20.28.png

Votes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines