shodkin Posted June 5, 2020 Share Posted June 5, 2020 Hello, Firstly apologies if this question has been asked before but I cant find a solution anywhere... I am trying to create a a 2D plan of a fairly simple road network for a temporary event. I have a base map showing the positions of the buildings, I have added perpendicular lines in between the buildings to get the centre points of the road and I can then draw a polyline through those points to give me a line going down the center of the road. I know that, centred on that line, I need enough space for a 2.5m path for vehicles and 1.5m path for pedestrians, so a 4m wide area in total. What I would like to be able to do is something similar to "Extrude along path" but for a polygon? So I can create 2 polygons, one 2.5m wide and another 1.5m wide, next to each other on the center line I have drawn. I know I can achieve something similar with the "Double Line Polygon Tool" (draw a 4m wide polygon along the centre line, then a 2.5m wide polygon along one edge and then a 1.5m wide polygon along the other edge and delete the original 4m wide polygon leaving the remaining 2.5m and 1.5m polygons) but I was hoping for a way of firstly, drawing both polygons at once, and secondly, being able to edit the path of the resulting polygons as you can when extruding an object along a path? instead of having to move the individual points that make up the resulting polygon. That way I can easily tweek the polygon while maintaining the width? I think what I'm looking for would be something like "Extend along Path"? But I cant see anything like it? I'm using VW2019 Quote Link to comment
Pat Stanford Posted June 5, 2020 Share Posted June 5, 2020 How about creating a Line Style with the required widths. Quote Link to comment
shodkin Posted June 6, 2020 Author Share Posted June 6, 2020 Hi Pat, thanks a lot. I ended up creating my own "profiles" using lines (1x line 2.5m + 1x line 1.5m) next to each other, then extruding them along the path of the center line I created, converting the "extrude along path" object to a NURBS group and then each NURBS inside the group back into a polygon and using add surface... Converting them to a NURBS first (rather that straight to polygons) meant that I could go into the group and select each "path way" and "road way" and individually to add the areas in one go rather than having to try and select all the associated polygons in one area. Quote Link to comment
Benson Shaw Posted June 7, 2020 Share Posted June 7, 2020 (edited) @shodkin sounds like lots of work to go in and out of 3d. w Would the 2d Offset tool work for this? offset the ctr line 1.5m to one side, then offset ctr line 2.5m to other side. In the offset tool prefs, choose whether to close the shapes ( yes, if center line should show on the drawing and so that colorfill can be added). In the tool mode choose whether to keep the source (probably yes for 1st offset, no for 2nd. or keep both but may want to delete after so no polys lurking under the road). intersections will likely need separate objects. -B Edited June 7, 2020 by Benson Shaw out on limb 1 Quote Link to comment
Benson Shaw Posted June 7, 2020 Share Posted June 7, 2020 or if the center line is actual center rather than boundary btw the 2 uses, offset 2m either side to establish one road edge, then offset back 2.5, then offset the new one 1.5 to establish the opposite road edge. or if boundary not needed, offset ctr line twice, 2m each side. c -B Quote Link to comment
shodkin Posted June 7, 2020 Author Share Posted June 7, 2020 Hi Benson, Thanks for this, its a lot closer to the elegant solution I was looking for. Many thanks Quote Link to comment
shodkin Posted July 2, 2020 Author Share Posted July 2, 2020 (edited) Hi, Thanks for all the responses. Sorry it's taken a while to get around to this but I thought I'd post the solution I came up with incase it is useful to anyone else... I ended up creating a VectorScript to do this, it had the advantage of allowing a lot more control over what is created and how! Plus it can be created to work on multiple lines in one go, rather than having to be manually repeated over and over as well as adding class info to each object automatically as it is created. In addition, the section at the beginning which reads in the path info (number of paths, width of each path etc) can also be read in from a symbol, which avoids having to enter all the information every time... procedure CreatePaths; var counter :integer; pathWidths :Dynarray[] of real; totalNumPaths :integer; pathBoundaries :Dynarray[] of handle; paths :Dynarray[] of handle; pathsCenterline :Dynarray[] of handle; lineAStart, lineAEnd, lineBStart, lineBEnd :vector; totalNumPathBoundaries :integer; pathNumber :integer; default, result :string; tempPathA, tempPathB :handle; tempInteger :integer; tempReal :real; temp :handle; currentCenterline :handle; highwayCenterlines :Dynarray of handle; totalCenterLines, activeCenterline :integer; begin {Check to see if at least one HIGHWAY centerline has been selected} if (FSActLayer <> Nil) then begin {Centerlines of selected HIGHWAYS are counted and array populated to hold them} totalCenterlines:=count(sel); Allocate highwayCenterlines[1..totalCenterlines]; activeCenterline:=1; {HIGHWAYS are added to array} while (activeCenterline <= totalCenterlines) do begin highwayCenterlines[activeCenterline]:= FSActLayer; SetName(highwayCenterlines[activeCenterline], Concat('Highway-Centerline-',Num2StrF(activeCenterline))); SetDSelect(FSActLayer); activeCenterline := activeCenterline + 1; end; {all HIGHWAY centerlines are now stored in "highwayCenterlines[]"} {Ask user for total number of PATHS to be created along the HIGHWAY} default :=''; result := StrDialog('Enter Number of Paths...', default); totalNumPaths := Str2Num(result); counter :=1; {Define an array to store the pathWidths as reals, total highway width is calculated and stored in last element (totalNumPaths+1)} Allocate pathWidths[1..totalNumPaths+1]; Allocate paths[1..totalNumPaths]; Allocate pathsCenterline[1..totalNumPaths]; {Asks the user to input the widths of the PATHS and stores them from left to right in the direction of the highway path} while (counter <= totalNumPaths) do begin {Input path width is stored in pathsWidth array} result := StrDialog(Concat('Enter width of Path ', Num2StrF(counter)), default); pathWidths[counter] := Str2Num(result); {total Highway width is updated and stored at end of array} pathWidths[totalNumPaths+1] := pathWidths[totalNumPaths+1] + pathWidths[counter]; counter := counter + 1; end; {all path widths are now stored in the pathWidths array with the total highway width stored at the end of array in element "totalNumPaths+1"} {populates the path boundaries with the centerline and outer boundaries} {NOTES: element 1 = HIGHWAY centerLine Element 2 = HIGHWAY righthand boundary Element 3 = HIGHWAY lefthand Boundary Element 4 = Final PATH boundary} activeCenterline:=1; while (activeCenterline <= totalCenterlines) do begin {Create an array to hold the PATH boundary lines, the 4 additional elements are required to store the final path boundaries and to store the centerline and boundaries for the HIGHWAY} totalNumPathBoundaries := totalNumPaths + 4; Allocate pathBoundaries[1..totalNumPathBoundaries]; {Creates the HIGHWAY centerline} pathBoundaries[1] := highwayCenterlines[activeCenterline]; SetName(pathBoundaries[1],Concat('boundry','centerline')); SetClass(pathBoundaries[1], 'Highway-Centerline'); SetFillColorByClass(pathBoundaries[1]); SetLWByClass(pathBoundaries[1]); SetLSByClass(pathBoundaries[1]); {creates the HIGHWAY top boundary and sets its name and class information} pathBoundaries[2] := OffsetPolyN(pathBoundaries[1], pathWidths[totalNumPaths+1]/2, false); SetName(pathBoundaries[2],Concat('boundry','top')); SetClass(pathBoundaries[2], 'Highway-Boundary'); SetFillColorByClass(pathBoundaries[2]); SetLWByClass(pathBoundaries[2]); SetLSByClass(pathBoundaries[2]); {creates the HIGHWAY bottom boundary and sets its name and class information} pathBoundaries[3] := OffsetPolyN(pathBoundaries[1], -pathWidths[totalNumPaths+1]/2, false); SetName(pathBoundaries[3],Concat('boundry','bottom')); SetClass(pathBoundaries[3], 'Highway-Boundary'); SetFillColorByClass(pathBoundaries[3]); SetLWByClass(pathBoundaries[3]); SetLSByClass(pathBoundaries[3]); {creates the final PATH boundary and sets its name and class information} pathBoundaries[4] := CreateDuplicateObject(pathBoundaries[3], NIL); SetName(pathBoundaries[4],Concat('boundry',Num2StrF(4))); SetClass(pathBoundaries[4], 'Path-Boundary'); SetFillColorByClass(pathBoundaries[4]); SetLWByClass(pathBoundaries[4]); SetLSByClass(pathBoundaries[4]); {increases the counter to the number of the next PATH to be created and begins creating the remaining PATHS} counter := 5; pathNumber :=1; while (counter <= totalNumPathBoundaries) do begin {Tempory PATH boundires are created to allow composed objects to be created later while retaining the original PATH boundaries} tempPathA := CreateDuplicateObject(pathBoundaries[counter-1], NIL); pathBoundaries[counter]:= OffsetPolyN(pathBoundaries[counter-1], pathWidths[pathNumber], false); {Classes and names are set for the PATH boundaries} SetClass(pathBoundaries[counter], 'Path-Boundary'); SetFillColorByClass(pathBoundaries[counter]); SetLWByClass(pathBoundaries[counter]); SetLSByClass(pathBoundaries[counter]); SetName(pathBoundaries[counter],Concat('boundry',Num2StrF(counter))); tempPathB := CreateDuplicateObject(pathBoundaries[counter], NIL); SetName(tempPathB, 'TempB'); {Retrieves the start and end points of the 2 temporary boundary paths and stores them in "lineStart" } GetPolylineVertex(tempPathA, 1, lineAStart.x, lineAStart.y, tempInteger, tempReal); GetPolylineVertex(tempPathA, getVertNum(tempPathA), lineAEnd.x, lineAEnd.y, tempInteger, tempReal); GetPolylineVertex(tempPathB, 1, lineBStart.x, lineBStart.y, tempInteger, tempReal); GetPolylineVertex(tempPathB, getVertNum(tempPathB), lineBEnd.x, lineBEnd.y, tempInteger, tempReal); {Deselects all objects on in the Vectorworks document} DSelectAll; {Draws 2 lines which links the 2 PATH boundaries to create 4 connected lines and makes sure they are selected in the document} moveTo(lineAStart.x, lineAStart.y); lineTo(lineBStart.x, lineBStart.y); setSelect(LNewObj); moveTo(lineBEnd.x, lineBEnd.y); lineTo(lineAEnd.x, lineAEnd.y); setSelect(LNewObj); {selects the 2 PATH boundaries so that both PATH boundaries and the 2 end lines are now selected in the document} setSelect(tempPathA); setSelect(tempPathB); {Composes the selected lines, which should be the 2 boundary lines and the 2 end lines, into a single polygon} DoMenuTextByName('Compose',0); {Assigns the newly created polygon to the "Path-Section" class} setSelect(LNewObj); temp := LNewObj; SetClass(FSActLayer, 'Path-Section'); SetFillColorByClass(FSActLayer); SetLWByClass(FSActLayer); SetLSByClass(FSActLayer); paths[pathNumber] := FSActLayer; {Creates a new centerline for the PATH section and adds it to the centerline array} pathsCenterline[pathNumber] := OffsetPolyN(tempPathA, (pathWidths[pathNumber]/2), false); SetClass(pathsCenterline[pathNumber], 'Path-Centerline'); counter := counter +1; pathNumber := pathNumber + 1; end; activeCenterline := activeCenterline +1; end end else {Script had been run with no objects selected} begin AlrtDialog('Please select a centerline!'); end; end; {Run the program} RUN(CreatePaths); Hope its of use to someone, and if anyone ends up making it a bit shorter/simpler... please repost! Many thanks Edited July 2, 2020 by shodkin 1 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.