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

How to calculate the new boundaries of an object after transformation?

Guide ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

I have an object inside a layer, the initial boundaries of which are known, but I cannot get them directly (this is part of the image) . Object are described in the standard way in document coordinates - top, left, right, bottom. I need to perform a series of transformations of the entire layer and after that get the new coordinates of the object inside it (transformation in this case is only a change in scale, image rotation is not performed). I easily coped with move (x+dx) (y+dy), but I got stuck on the transformation with the center set manually (the coordinates of this point are known - x, y). It seems that I understand this combination of move + scale and a proportional change coordinates is required depending on their distance from the point x,y, but I cannot deduce the correct formula for calculating the new values ​​of top, left, right, bottom. Can someone help me with this?

2021-07-28_16-14-48.png

P.S. it is clear that we can copy an object to a new layer and perform its transformation with the same parameters as the main layer (this is how the script works at the moment), but I want to speed up the script and get rid of unnecessary transformations (that is, get coordinates by calculation )

TOPICS
Actions and scripting

Views

262

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

Guide , Jul 28, 2021 Jul 28, 2021
 this.transform = function (dX, dY, scale, x, y, subject) {
        (r = new ActionReference()).putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        d.putEnumerated(s2t('freeTransformCenterState'), s2t('quadCenterState'), s2t('QCSIndependent'));
        ((d1 = new ActionDescriptor())).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), x);
        d1.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), y);
       
...

Votes

Translate

Translate
Adobe
Guide ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

 this.transform = function (dX, dY, scale, x, y, subject) {
        (r = new ActionReference()).putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        d.putEnumerated(s2t('freeTransformCenterState'), s2t('quadCenterState'), s2t('QCSIndependent'));
        ((d1 = new ActionDescriptor())).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), x);
        d1.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), y);
        d.putObject(s2t('position'), s2t('paint'), d1);
        (d2 = new ActionDescriptor()).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), dX);
        d2.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), dY);
        d.putObject(s2t('offset'), s2t('offset'), d2);
        d.putUnitDouble(s2t('width'), s2t('percentUnit'), scale);
        d.putUnitDouble(s2t('height'), s2t('percentUnit'), scale);
        d.putEnumerated(s2t('interfaceIconFrameDimmed'), s2t('interpolationType'), s2t('bicubic'));
        executeAction(s2t('transform'), d, DialogModes.NO);

        if (subject) {
            with (subject) {
                var dV = (height * scale / 100 - (bottom - top)),
                    dH = (width * scale / 100 - (right - left));
                top = top - (dV * (y - top) / height) + dY
                bottom = bottom + (dV * (bottom - y) / height) + dY
                left = left - (dH * (x - left) / width) + dX
                right = right + (dH * (right - x) / width) + dX
                height = height * scale / 100
                width = width * scale / 100
            }
    }

* where subject is object with bounding box coordinates

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 ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

Can you edit your code to working version to let me try out it on some layer with an object inside?

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 ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

LATEST

It is difficult for me to provide a working code, since I am getting the coordinates of the object with the layer from another program. But there is no difference, you can just calculate the bounding rect of the current layer after transformation.

 

var lr = new AM('layer'),
subject = lr.descToObject(lr.getProperty('boundsNoEffects'));

lr.transform(100, 200, 150, 70, 120, subject)
var newBounds = lr.descToObject(lr.getProperty('boundsNoEffects'));
alert ('calculated:\ntop: '+subject.top +', left: ' +subject.left + ', right: ' + subject.right + ', bottom: ' + subject.bottom + '\nreal:\ntop: '
+newBounds.top +', left: ' +newBounds.left + ', right: ' +newBounds.right + ', bottom: ' + newBounds.bottom + '\nreal:\n')

function AM(target, order) {
    var s2t = stringIDToTypeID,
        t2s = typeIDToStringID;

    target = s2t(target)
    
    this.getProperty = function (property, descMode, id, idxMode, parent, parentIdx) {
        property = s2t(property);
        (r = new ActionReference()).putProperty(s2t('property'), property);
        id != undefined ? (idxMode ? r.putIndex(target, id) : r.putIdentifier(target, id)) :
            r.putEnumerated(target, s2t('ordinal'), order ? s2t(order) : s2t('targetEnum'));
        if (parent) r.putIndex(s2t(parent), parentIdx);
        return descMode ? executeActionGet(r) : getDescValue(executeActionGet(r), property)
    }

    this.descToObject = function (d) {
        var o = {}
        for (var i = 0; i < d.count; i++) {
            var k = d.getKey(i)
            o[t2s(k)] = getDescValue(d, k)
        }
        return o
    }

    this.transform = function (dX, dY, scale, x, y, subject) {
        (r = new ActionReference()).putEnumerated(s2t('layer'), s2t('ordinal'), s2t('targetEnum'));
        (d = new ActionDescriptor()).putReference(s2t('null'), r);
        d.putEnumerated(s2t('freeTransformCenterState'), s2t('quadCenterState'), s2t('QCSIndependent'));
        ((d1 = new ActionDescriptor())).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), x);
        d1.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), y);
        d.putObject(s2t('position'), s2t('paint'), d1);
        (d2 = new ActionDescriptor()).putUnitDouble(s2t('horizontal'), s2t('pixelsUnit'), dX);
        d2.putUnitDouble(s2t('vertical'), s2t('pixelsUnit'), dY);
        d.putObject(s2t('offset'), s2t('offset'), d2);
        d.putUnitDouble(s2t('width'), s2t('percentUnit'), scale);
        d.putUnitDouble(s2t('height'), s2t('percentUnit'), scale);
        d.putEnumerated(s2t('interfaceIconFrameDimmed'), s2t('interpolationType'), s2t('bicubic'));
        executeAction(s2t('transform'), d, DialogModes.NO);

        if (subject) {
            with (subject) {
                var dV = (height * scale / 100 - (bottom - top)),
                    dH = (width * scale / 100 - (right - left));
                top = top - (dV * (y - top) / height) + dY
                bottom = bottom + (dV * (bottom - y) / height) + dY
                left = left - (dH * (x - left) / width) + dX
                right = right + (dH * (right - x) / width) + dX
                height = height * scale / 100
                width = width * scale / 100
            }
        }
    }

    function getDescValue(d, p) {
        switch (d.getType(p)) {
            case DescValueType.OBJECTTYPE: return (d.getObjectValue(p));
            case DescValueType.LISTTYPE: return d.getList(p);
            case DescValueType.REFERENCETYPE: return d.getReference(p);
            case DescValueType.BOOLEANTYPE: return d.getBoolean(p);
            case DescValueType.STRINGTYPE: return d.getString(p);
            case DescValueType.INTEGERTYPE: return d.getInteger(p);
            case DescValueType.LARGEINTEGERTYPE: return d.getLargeInteger(p);
            case DescValueType.DOUBLETYPE: return d.getDouble(p);
            case DescValueType.ALIASTYPE: return d.getPath(p);
            case DescValueType.CLASSTYPE: return d.getClass(p);
            case DescValueType.UNITDOUBLE: return (d.getUnitDoubleValue(p));
            case DescValueType.ENUMERATEDTYPE: return [t2s(d.getEnumerationType(p)), t2s(d.getEnumerationValue(p))];
            default: break;
        };
    }
}

PS. I would like to recalculate coordinates after rotation. Now I don't need it, but one day it might come in handy.

 

 

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 ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

What kind of layer is it? Do you mean by layer the entire gray area, while the blue square is an object with some x, y point inside? Or gray area is some background of other layer while the mentioned layer is a blue square, that said, the x, y object would be then an object?

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 ,
Jul 28, 2021 Jul 28, 2021

Copy link to clipboard

Copied

gray area - layer, blue square - object in this layer

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