Jump to content

How can script determine if an Oval was drawn Tall or Wide (or Flipped)...?


Recommended Posts

This is a quick script to mark the Foci of an Ellipse.

 

It just does math on a selected oval. (It does no checking yet, it will do the math on anything.)

 

Weird error...

 

this works fine on ovals drawn "long", rotated, flipped, whatever, the Foci get marked right.

 

but if the oval was drawn "tall" the math is done on the wrong dimensions and the markings are wrong.

 

you can redraw a "wrong" oval by drawing it long-way-first and then adjusting it to any orientation you need, it will then get marked correctly.

 

Maybe this involves the handle to the Bounding Box?

 

Maybe there's some way to determine if an object is reoriented...?

 

I have attached a file with the script and some examples, would love to see if anyone has an insight. i always learn cool things here.

 

—AE

 

 

 

PROCEDURE EllipseMarker;

VAR

    obHd : HANDLE;
    x, y,
    MajorAxis,
    MinorAxis,
    Foci,
    ObjectWidth,
    ObjectHeight,
    thePerimeter,
    layScale,
    TheOffset,
    theAngle,
    theAngleModifier : REAL;
    
    thePerimeterString : STRING;

BEGIN
    obHd := LSActLayer;
    
    layScale:= GetLScale(ActLayer);
    
    TheOffset := (layscale*.25);
    WHILE NOT(obHd=NIL) DO BEGIN
        HCenter(obHd, x, y);
        theAngle := HAngle(obHd);
        
        ObjectHeight := HHeight(obHd);
        ObjectWidth := HWidth(obHd);
    
        If ObjectHeight > ObjectWidth then
            begin
            MajorAxis := ObjectHeight;
            MinorAxis := ObjectWidth;
            theAngleModifier := 90;
            end
        else
            begin
            MajorAxis := ObjectWidth;
            MinorAxis := ObjectHeight;
            end;

    Foci := Sqrt( SQR(MajorAxis/2) - SQR(MinorAxis/2) );

    BeginGroup;
    
    
        MoveTo(x-ObjectWidth/2-TheOffset, y);
        LineTo(x+ObjectWidth/2+TheOffset, y);
        
        MoveTo(x, y-ObjectHeight/2-TheOffset);
        LineTo(x, y+ObjectHeight/2+TheOffset);

        MoveTo(x-Foci, y-TheOffset/2);
        LineTo(x-Foci, y+TheOffset/2);
        Locus(x-Foci, y);
        TextOrigin(x-Foci, y-TheOffset/2);
        CreateText('F1');
        
        MoveTo(x+Foci, y-TheOffset/2);
        LineTo(x+Foci, y+TheOffset/2);
        Locus(x+Foci, y);
        TextOrigin(x+Foci, y-TheOffset/2);
        CreateText('F2');
           
        BeginPoly;
        ClosePoly;
        AddPoint(x+Foci, y);
        AddPoint(x-Foci, y); 
        AddPoint(x, y+ObjectHeight/2);
        EndPoly;
        SetLSN(LNewObj, -561);

        thePerimeter := HPerimN(LNewObj);
        thePerimeterString := Num2Str(1,thePerimeter);
        TextOrigin(x, y+TheOffset);
        CreateText(Concat('String ',thePerimeterString,'"'));

        EndGroup;
       
        DSelectAll;
        SetSelect(LNewObj);
        RotatePoint(x,y,theAngle+theAngleModifier);
        DSelectAll;
        
        obHd := PrevSObj(obHd);

    END;
END;
RUN(EllipseMarker);

 

Script to Mark Ellipse.vwx

Edited by AEChadwick
too many "quotes"
Link to comment
1 hour ago, Julian Carr said:

These two calls might help:

 

PROCEDURE GetBBox(h1, x1, y1, x2, y2);

FUNCTION IsObjectFlipped(h1) : BOOLEAN;

 

hey man, thank you for taking a look.

 

("IsObjectFlipped" applies to 3D i think?)

 

I tried checking "IsFlipped" but the results made no difference. 

 

as for GetBBox... I suppose i could get the bounding points and make a comparison to see where "TopLeft" falls relative to the center point, but that seems like an intense solution. I'll save that in my backpocket.

 

—Æ

 

 

Link to comment

GetBBox() will easily tell you the orientation of the oval if you compare the distance between x1 and x2 with the distance between y1 and y2. If the latter is greater then it was drawn tall. I think IsFlipped() will only work with objects that store the flip status, which likely doesn't happen with symmetrical 2D objects like ovals.

Link to comment

bugger me, but GetBBox doesn't seem to discern rotation/origin/whatever...

 

a quick add to get points

 

    GetBBox(obHd, Oval_p1X, Oval_p1Y, Oval_P2X, Oval_P2Y);

 

 a quick add to mark those points

 

        TextOrigin(Oval_p1X, Oval_p1Y);
        
        CreateText('P1');
        
        TextOrigin(Oval_P2X, Oval_P2Y);
        
        CreateText('P2');

 

and regardless of wrongness, upper left is upper left and lower right is lower right.

 

i'll look more in the morning

Screen Shot 2021-08-26 at 7.36.47 PM.png

Link to comment
14 hours ago, Julian Carr said:

The bounding box is only that. It knows nothing of the rotation state and will only be of use to you if the oval is drawn using the first mode (box mode).

 

totally. plus, i can tell if the oval is tall or wide just by comparing it's height and width.

 

the bounding box... it actually DOES retain something of the rotation state, i just have no idea how to access it: if you scrub over the handles they will identify "top left" and "bottom left"--and those positions do NOT change with rotation, they remain true to "how was it originally drawn" (ie., top left might end up in the lower left corner). If i could access that information, i could compare it to width and determine if the oval was drawn tall and then rotated.

 

(in the screenshot above? the Left Oval is drawn-tall-then-rotated, P1 identifies as "upper right." The Right Oval was drawn long and left in place, P1 identifies as "upper left")

 

it's a weird situation, that's why i'm grateful for the help.

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...