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

How can I control the coordinate system?

Community Beginner ,
Nov 01, 2016 Nov 01, 2016

Copy link to clipboard

Copied

My puzzle is somewhat simple:

Suppose you have a rectangle and you ask for its geometric bounds. Then you compute a new size, with the same values for the upper left corner, and use those values to resize. What happens is that the rectangle moves quite a distance and I expect its upper left corner to remain in place.

Here's a skeleton script fragment - starting with the variable myRect pointing to a rectangle which is on a page in a spread:

  myBounds = myRect.geometricBounds

myY1 = myBounds[0]

myX1 = myBounds[1]

myY2 = myBounds[2]

myX2 = myBounds[3]

newY2 = myY2 + 20

newX2 = myX2 +30

myRect.reframe(CoordinateSpaces.SPREAD_COORDINATES,[[myY1,myX1],[newY2,newX2]])

I also tried this with the PAGE_COORDINATES option, but then the frame just disappeared from view, so it made an enormous move!

I'd really appreciate any help in preventing the corner's motion. Thanks in advance.

TOPICS
Scripting

Views

829

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

Mentor , Nov 01, 2016 Nov 01, 2016

Hi,

You can use a "new" geometricBounds to resize object directly.

I mean:

myRect.geometricBounds = [myY1, myX1, newY2, newX2];

However  - to go deeper into coordinate system details see this link:

Marc Autret lecture

Jarek

Votes

Translate

Translate
Mentor ,
Nov 01, 2016 Nov 01, 2016

Copy link to clipboard

Copied

Hi,

You can use a "new" geometricBounds to resize object directly.

I mean:

myRect.geometricBounds = [myY1, myX1, newY2, newX2];

However  - to go deeper into coordinate system details see this link:

Marc Autret lecture

Jarek

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 Beginner ,
Nov 02, 2016 Nov 02, 2016

Copy link to clipboard

Copied

Thanks everyone,

Just rewriting the geometricBounds property value did the trick, without all the extra messing around that some of you suggested. It's amazing how simple a problem's solution can be if you think in a good direction!!

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 Beginner ,
Nov 02, 2016 Nov 02, 2016

Copy link to clipboard

Copied

I should have given big credit, along with my thanks, to Jarek, for thinking in the best direction!!

Dick

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 ,
Nov 02, 2016 Nov 02, 2016

Copy link to clipboard

Copied

Hi Dick,

then rotate your selected object a bit and try to work with geometricBounds.

Alternatively use reframe() with CoordinateSpaces.INNER_COORDINATES and see the differences:

// Example:

// Values here meant as millimeters

// Converted to points:

var s = app.selection[0];

var xPlus = UnitValue( 30 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);

var yPlus = UnitValue( 20 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);

var topLeft = s.resolve(AnchorPoint.TOP_LEFT_ANCHOR, CoordinateSpaces.INNER_COORDINATES)[0];

var bottomRight = s.resolve(AnchorPoint.BOTTOM_RIGHT_ANCHOR, CoordinateSpaces.INNER_COORDINATES)[0];

// reframe() and other transform methods always use points as unit:

s.reframe(CoordinateSpaces.INNER_COORDINATES, [topLeft, [bottomRight[0] + xPlus, bottomRight[1] + yPlus]] );

Regards,
Uwe

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 ,
Nov 03, 2016 Nov 03, 2016

Copy link to clipboard

Copied

LATEST

For what it's worth (not too much on an InDesign forum) I spend most of my scripting time on Illustrator a land where there are no mm or inches only points. It actually makes life pretty simple.

To convert mm or whatevers  to points one can use

String.prototype.pt = function() {

    var x, m, value, unit;

    if (!this.pt.table) {

        this.pt.table = {

            'in': 72,

            '"': 72,

            'inches': 72,

            'inch': 72,

            'mm': 72 / 24.1,

            'feet': 72 * 12,

            "'": 72 * 12,

            'yard': 72 * 12 * 3,

            'cm': 72 / 2.41,

            'm': 7200 / 2.41,

            'km': 7200000 / 2.41,

            'pt': 1,

            'pts': 1,

            'point': 1,

            'points': 1

        }

    }

    x = (this.toLowerCase()).replace(/[^-.\da-z"']+/g, '');

    value = +x.replace(/[^\d.]+/g, '');

    unit = x.replace(/[^a-z'"]+/g, '');

    if (unit === '') { unit = 'pt'; }

    if (!(unit in this.pt.table)) {

        return 'Ehr I don\'t know this unit';

    }

    if (value === '') {

        return 'Funny number';

    }

    return value * this.pt.table[unit];

}

function inches(x) {

    return 72 * x;

}

function mm(x) {

    return 72 * x / 25.1

}

alert("23.6'".pt() + inches(2) + mm(6));

The inches and mm functions are quite handy and

var xPlus = '30mm'.pt();

or

xPlus = mm(30);

are both somewhat less cumbersome than

var xPlus = UnitValue( 30 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);

var xPlus = UnitValue( '30mm').as('pt');

FWIW

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
People's Champ ,
Nov 01, 2016 Nov 01, 2016

Copy link to clipboard

Copied

What Jarek said...

So, if you want to keep it simple, just stick to reading and writing geometricBounds of the object. Just remember that when you're writing the geometricBounds, you have to supply a full array. You can't write myObject.geometricBounds[1] = 30. You'd have to write: myObject.geometricBounds = [1,2,3,4];

However, really it is more correct and better to use reframe(). But in that case, to stay consistent, don't get the bounds of the object with geometricBounds, but with the resolve() method. Something like this:

s = app.selection[0];

topLeft = s.resolve(AnchorPoint.TOP_LEFT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES)[0];

bottomRight = s.resolve(AnchorPoint.BOTTOM_RIGHT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES)[0];

s.reframe(CoordinateSpaces.SPREAD_COORDINATES, [topLeft, [bottomRight[0] + 20, bottomRight[1] + 20]]);

Ariel

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 ,
Nov 01, 2016 Nov 01, 2016

Copy link to clipboard

Copied

Hi Dick,

just one thing to add:


reframe() is always working with Points as unit.

+ 20 in Ariel's example will actually add 20 points.


Even if your ruler guides are showing e.g. millimeters.

You cannot use strings with reframe() like one can do with geometric bounds.
E.g. if you want to work with millimeters:

var myNewGeometricBounds = [0,0,"100 mm","70mm"];

app.selection[0].geometricBounds = myNewGeometricBounds;

Instead you first have to convert your intended measurements to points:

// Example:

// Values here meant as millimeters

// Converted to points:

var s = app.selection[0];

var xPlus = UnitValue( 30 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);

var yPlus = UnitValue( 20 , MeasurementUnits.MILLIMETERS).as(MeasurementUnits.POINTS);

var topLeft = s.resolve(AnchorPoint.TOP_LEFT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES)[0];

var bottomRight = s.resolve(AnchorPoint.BOTTOM_RIGHT_ANCHOR, CoordinateSpaces.SPREAD_COORDINATES)[0];

// reframe() and other transform methods always use points as unit when in comes to coordinates:

s.reframe(CoordinateSpaces.SPREAD_COORDINATES, [topLeft, [bottomRight[0] + xPlus, bottomRight[1] + yPlus]] );

Regards,
Uwe

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 ,
Nov 02, 2016 Nov 02, 2016

Copy link to clipboard

Copied

> Instead you first have to convert your intended measurements to points:

It's easier to set the script engine's default to points:

app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;

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
Community Expert ,
Nov 02, 2016 Nov 02, 2016

Copy link to clipboard

Copied

Hi Peter,

but that wouldn't do the conversion, wouldn't it?

Example:
I like to expand my selected rectangle by 40 millimeters in x-direction.

Setting the measurementUnit with scriptPreferences will not help with that.

I still would have to feed my desired value 40 converted to points to the reframe() method.

Hm, or do I see something wrong here?

Regards,
Uwe

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 ,
Nov 02, 2016 Nov 02, 2016

Copy link to clipboard

Copied

> but that wouldn't do the conversion, wouldn't it?

True. I'm just a bit points-biased. I always set the script engine to points and add measure in bare numbers, so that's always points. But if you want to add 40mm you'll have to use UnitValue() to convert that to points.

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