AEChadwick Posted August 26, 2021 Share Posted August 26, 2021 (edited) 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 August 27, 2021 by AEChadwick too many "quotes" Quote Link to comment
Julian Carr Posted August 26, 2021 Share Posted August 26, 2021 These two calls might help: PROCEDURE GetBBox(h1, x1, y1, x2, y2); FUNCTION IsObjectFlipped(h1) : BOOLEAN; Quote Link to comment
AEChadwick Posted August 26, 2021 Author Share Posted August 26, 2021 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. —Æ Quote Link to comment
Julian Carr Posted August 27, 2021 Share Posted August 27, 2021 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. Quote Link to comment
AEChadwick Posted August 27, 2021 Author Share Posted August 27, 2021 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 Quote Link to comment
Julian Carr Posted August 27, 2021 Share Posted August 27, 2021 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). Quote Link to comment
AEChadwick Posted August 27, 2021 Author Share Posted August 27, 2021 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. Quote Link to comment
Recommended Posts
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.