# Extending a line from it's center

## Recommended Posts

I've created a PIO that selects all the lines from the visible layer on the drawing.  Now I simple want to increase each line's length by 2" (user defined), from it's center.  How do I make sure it's length changes from it's center?

Dave

Lines in Vectorscript and Python are defined by their beginning and ending points. So you can change the length, but that will just change the ending point. You will have to calculate the distance that you need and move the line by that amount as well as the amount you need to change the length of the line. Probably need to break our your high school trigonometry book to calculate the X/Y movement based on the angle of the line.

Or you might be able to use the HScale command which takes the center of the object as the point to scale by. You can find the center of a line by using the difference between the corner points of the Bounding Box GetBBox(Handle).

Thank you for the clarity.  I was hoping there was a way of selecting the center of the line and then changing it's length like I can do in the OIP manually, without doing all the math, but I guess not.  Bummer.  HScale might work for me though.  Thank you once again.

Dave

Hopefully one of the other gurus will see this post and tell me I am wrong ;-)

Pat is right. Scaling the line using HScale2D is the way to go and it is easy enough:

Procedure T;
VAR
h1 : HANDLE;
rCenterX, rCenterY : REAL;
rScaleFactor : REAL;
rExistLen, rNewLen : REAL;
BEGIN
h1 := FSActLayer;
HCenter(h1, rCenterX, rCenterY);
rExistLen := HLength(h1);
rNewLen := RealDialog('New Length?', Concat(rExistLen));
rScaleFactor := rNewLen / rExistLen;
HScale2D(h1, rCenterX, rCenterY, rScaleFactor, rScaleFactor, False);
Redraw;
END;
Run(T);

I hate it when I am right about stuff that could be so much easier.  :-(

Just for variety, here is a vector approach to do the same thing. It's just a little more code than Julian's scaling approach, and to the original request it will increment every line on visible layers. If you want the script to only work on the Active Layer, then change the last "2" to a "0" in the following line:

ForEachObjectInLayer(GrowLine, 0, 0, 2);        { All objects, Shallow, Visible layers }

ForEachObjectInLayer(GrowLine, 0, 0, 0);        { All objects, Shallow, Current layer }

```Procedure GrowLinesByInc;
{ Grow each line on visible layers by a user input length. If the user input is positive }
{ the line length increases, if it is negative, the line length decreases. }
VAR
dLength : REAL;

function GrowLine(H :Handle) :Boolean;
{ Use global variable "dLength" to calculate a vector in the same direction }
{ of each line and add half of it to each end. }
Var
P1, P2, Vdelta :Vector;
Begin
if (GetTypeN(H) = 2) then begin		{ type 2 is a LINE }
GetSegPt1(H, P1.x, P1.y);	{ start point of line }
GetSegPt2(H, P2.x, P2.y);	{ stop point of line }
Vdelta := UnitVec(P2 - P1) * dLength/2;
P1 := P1 - Vdelta;		{ move away from center }
P2 := P2 + Vdelta;		{ move away from center }
SetSegPt1(H, P1.x, P1.y);	{ new start point of line }
SetSegPt2(H, P2.x, P2.y);	{ new stop point of line }
end;		{ if }
end;		{ GrowLine }

BEGIN
dLength := RealDialog('Length increment?', '0');
if not DidCancel do
ForEachObjectInLayer(GrowLine, 0, 0, 2);	{ All objects, Shallow, Visible layers }
END;
Run(GrowLinesByInc);```

Raymond

WOW!!  I feel like I got the "A" team jumping on this, and so interesting to see how each of you would tackle this issue.  I like the way Julian came at my problem so I took his code and revised it a bit to meet my needs.  It still needs to be refined a bit but it does what I need it to do for now.  I probably lost hours of time trying to figure out which selection procedures to use between the Selection class and the Document List Handling class.  The code you all shared with me was super helpful with helping me steer my thoughts and direction.  Thank you all for offering your help.  The three of you are the pillars of this Forum.

I wrote this code because sometimes I get DWG files where the end points of lines to exactly match, so when I use the 2D polygon, paint bucket, tool, I'm unable to fill different cavities quickly.  So I figured a quick little script to extend all the lines 2" in either direction should do the trick, and then when I was done, I could use the same tool to restore everything back to normal.

Dave

PROCEDURE IncreaseLength;

VAR

h1 : HANDLE;

i,k: INTEGER;

rCenterX, rCenterY : REAL;

rScaleFactor : REAL;

rExistLen, rNewLen : REAL;

MyH: DYNARRAY [] OF HANDLE;

BEGIN

SelectObj(T=2);

i:=NumSObj(ActLayer);

ALLOCATE MyH[1..i];

h1:=FSActLayer;

FOR k:=1 TO i DO BEGIN

MyH[k]:=h1;

h1:=NextSObj(h1);

END;

DSelectAll;

rNewLen := RealDialog('Length increase:','2');

k:=1;

WHILE (k <= i) & (i <> 0)DO BEGIN

HCenter(MyH[k], rCenterX, rCenterY);

rExistLen := HLength(MyH[k]);

rScaleFactor := (rExistLen+rNewLen) / rExistLen;

SetSelect(MyH[k]);

Scale(rScaleFactor, rScaleFactor);

DSelectAll;

k:=k+1;

END;

END;

Run(IncreaseLength);

While is seems logical to try and emulate how you work with the mouse to select objects then edit them in some way, if you want to get into scripting then you'll find it much easier to work with handles. And the single most useful call for this is ForEachObject(), because it uses criteria to choose what gets processed. This can be object type, class, layer, colour, selection state, etc. Using FEO would look something like this:

Procedure T;
VAR
grNewLen : REAL;

Procedure DoIt(h1 : HANDLE);
VAR
rCenterX, rCenterY : REAL;
rScaleFactor : REAL;
rExistLen : REAL;
BEGIN
HCenter(h1, rCenterX, rCenterY);
rExistLen := HLength(h1);
rScaleFactor := (rExistLen + grNewLen) / rExistLen;
HScale2D(h1, rCenterX, rCenterY, rScaleFactor, rScaleFactor, False);
END;

BEGIN { main }
grNewLen := RealDialog('New Length?', '2');
IF NOT DidCancel THEN ForEachObject(DoIt, (T = Line));
Redraw;
END;
Run(T);

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

×   Pasted as rich text.   Restore formatting

Only 75 emoji are allowed.

×   Your previous content has been restored.   Clear editor

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

×