Skip to main content
Known Participant
November 1, 2016
Answered

How can I control the coordinate system?

  • November 1, 2016
  • 3 replies
  • 1270 views

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.

This topic has been closed for replies.
Correct answer Jump_Over

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

3 replies

Community Expert
November 2, 2016

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

Peter Kahrel
Community Expert
Community Expert
November 2, 2016

> 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

Community Expert
November 2, 2016

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

TᴀW
Legend
November 1, 2016

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

id-extras.com | InDesign tools & scripts for typesetters, form designers, and translators
Jump_Over
Jump_OverCorrect answer
Legend
November 1, 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

Dick KainAuthor
Known Participant
November 2, 2016

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!!

Dick KainAuthor
Known Participant
November 2, 2016

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

Dick