BillW Posted May 9 Share Posted May 9 There is a 2D call for "Is 2D Poly Clockwise" ie GetObjectVariableBoolean(polyH,652); There is no 3D equivalent as far as I can tell. Tried the following code but is unreliable. Has anyone managed to crack this problem with Vectorscript? procedure test; VAR polyH : HANDLE; x1,y1,z1,x2,y2,z2,x3,y3,z3,dval : REAL; v1,v2 : VECTOR; direction : STRING; begin polyH := fsactlayer; GetPolyPt3D(polyH,0,x1,y1,z1); {vertex 1} GetPolyPt3D(polyH,1,x2,y2,z2); {vertex 2} GetPolyPt3D(polyH,2,x3,y3,z3); {vertex 3} v1.x := x2-x1; v1.y := y2-y1; v1.z := z2-z1; {first edge} v2.x := x3-x2; v2.y := y3-y2; v2.z := z3-z2; {second edge} dval := DotProduct(unitvec(v1),unitvec(v2)); if dval > 0 then direction := 'Clockwise' else direction := 'Anteclockwise'; message(direction); end; run(test); Quote Link to comment
Marionette Maven Marissa Farrell Posted May 9 Marionette Maven Share Posted May 9 Here's the Python code that will potentially be used in a combo Is Clockwise node for both 2D and 3D inputs. My testing so far shows this to be accurate. Maybe it can be useful/translated into VS? @Marionette.NodeDefinition class Params(metaclass=Marionette.OrderedClass): # APPEARANCE this = Marionette.Node("Is Clockwise 2D/3D OPT") this.SetDescription("Determines if the polygon is clockwise oriented (works for both 2D and 3D polygons).") # INPUT PORTS poly = Marionette.PortIn(vs.Handle(0), "Polygon Handle") poly.SetDescription("A 2D or 3D polygon.") # OUTPUT PORTS isCW = Marionette.PortOut("Clockwise Orientation") isCW.SetDescription("True if the polygon is clockwise oriented, False otherwise.") def RunNode(self): def is_clockwise(points): signed_area = sum( (points[i][0] * points[(i + 1) % len(points)][1] - points[(i + 1) % len(points)][0] * points[i][1]) for i in range(len(points)) ) # Negative signed area indicates clockwise orientation return signed_area < 0 # Input polygon handle hPoly = self.Params.poly.value # Validate input if hPoly == vs.Handle(0): self.Params.isCW.value = None return # Determine if the polygon is 2D or 3D numverts = vs.GetVertNum(hPoly) if numverts < 3: # Less than 3 vertices cannot form a valid polygon self.Params.isCW.value = None return # Collect vertices and project to 2D (ignore z-coordinate if 3D) if vs.GetTypeN(hPoly) == 25: # 3D Polygon polygon_points = [vs.GetPolyPt3D(hPoly, i)[:2] for i in range(numverts)] else: # 2D Polygon polygon_points = [vs.GetPolyPt(hPoly, i) for i in range(numverts)] # Determine orientation result = is_clockwise(polygon_points) # Assign output self.Params.isCW.value = result Quote Link to comment
BillW Posted May 9 Author Share Posted May 9 Thanks Marissa. I did think of ditching the Z value as your code but was worried about the instance of a 3D polygon face aligned truely vertical. Will give it a try. The reason for needing this check, is when a 3D object is converted to 3D polygons, I want to check orientation and set accordingly and in the instance of an import that has mixed orientations I want all 3D polygons to have the same orientation ie facing IN or OUT Quote Link to comment
BillW Posted May 9 Author Share Posted May 9 I've just had a eurika moment. I manually reverse a polygon/polyline direction by looping through the vertices and rebuilding. A simpler solution is below which seem to work fine, although the first vertex seem to change which mimics the "Reverse Direction" button in the OIP for polygons. procedure test; procedure reversepoly(polyH : HANDLE); begin SetObjectVariableBoolean(polyH,652,NOT (GetObjectVariableBoolean(polyH,652))); end; begin reversepoly(fsactlayer); end; run(test); Quote Link to comment
BillW Posted May 9 Author Share Posted May 9 (edited) I think I have come up with a vectorscript version of "is_clockwise" for 3D polygons only I checked the python output from (points[i][0] * points[(i + 1) % len(points)][1] - points[(i + 1) % len(points)][0] * points[i][1]) with for i in range(10): msg = str(i)+' '+str((i + 1) % 10) vs.AlrtDialog(msg) which seemed to return 0 1, 1 2, 2 3 etc from points[i][0] and points[(i + 1) % len(points)] Edit: forgot the polygon closing edge procedure test; function is_clockwise(polyH : HANDLE) : BOOLEAN; VAR i,vnum : INTEGER; p1,p2,p3 : POINT; signedarea,val : REAL; z1 : REAL; begin signedarea := 0; vnum := GetVertNum(polyH); GetPolyPt3D(polyH,0,p1.x,p1.y,z1); p3 := p1; {store first vertex} for i := 1 to vnum-1 do begin GetPolyPt3D(polyH,i,p2.x,p2.y,z1); val := (p1.x * p2.y) - (p2.x * p1.y); p1 := p2; signedarea := signedarea + val; end; {closing edge} p2 := p3; val := (p1.x * p2.y) - (p2.x * p1.y); signedarea := signedarea + val; is_clockwise := (signedarea < 0); end; begin message('Is clockwise ',is_clockwise(FSActLayer)); end; run(test); Edited Tuesday at 12:11 PM by BillW 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.