10 Replies Latest reply on Nov 3, 2016 6:08 AM by Trevorׅ

How can I control the coordinate system?

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

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.

• 1. Re: How can I control the coordinate system?

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

• 2. Re: How can I control the coordinate system?

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];

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

Ariel

• 3. Re: How can I control the coordinate system?

Hi Dick,

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;
```

```// 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);

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

• 4. Re: How can I control the coordinate system?

> 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

• 5. Re: How can I control the coordinate system?

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

• 6. Re: How can I control the coordinate system?

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

• 7. Re: How can I control the coordinate system?

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

• 8. Re: How can I control the coordinate system?

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

Dick

• 9. Re: How can I control the coordinate system?

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

• 10. Re: How can I control the coordinate system?

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
}
```

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