here’s my first attempt at writing a tool type of script:
what it’s supposed to do:
• let you select two lines (which don’t necessarily have to share an endpoint) and the angle is returned
• pick one point on a polyline and the angle nearest the click is returned.
import rhinoscriptsyntax as rs
def pLine(line1):
polyPts = rs.CurveEditPoints(line1[0])
##################################################### Question 1
polyPts= rs.coerce3dpointlist(polyPts)
pcp= rs.PointArrayClosestPoint (polyPts, line1[3])
if pcp == (len(polyPts)-1):
polyPts.insert(0,0)
vertex= polyPts[pcp]
endpt1= polyPts[pcp-1]
endpt2= polyPts[pcp+1]
##################################################### Question 2
if pcp == 0:
vertex= polyPts[1]
endpt1= polyPts[0]
endpt2= polyPts[2]
vec1= rs.VectorCreate (vertex, endpt1)
vec2= rs.VectorCreate (vertex, endpt2)
angle= rs.VectorAngle(vec1, vec2)
print 'Angle = '+str(angle)
def twoLines(line1,line2):
match= rs.CurveDirectionsMatch(line1[0], line2[0])
if match == False:
rs.ReverseCurve(line1[0])
line1= rs.CurvePoints(line1[0])
line2= rs.CurvePoints(line2[0])
pt1= rs.coerce3dpoint(line1[0])
pt2= rs.coerce3dpoint(line1[1])
pt3= rs.coerce3dpoint(line2[0])
pt4= rs.coerce3dpoint(line2[1])
angle= rs.Angle2 ([pt1,pt2], [pt3,pt4])
print 'Angle = '+str(angle[0])
def input ():
line1 = rs.GetObjectEx('Pick a line or a point on polyline')
if not line1: return
if not line1[2] == 1:
print 'MUST SELECT WITH A MOUSE CLICK'
return
############################################################## Question 3
if rs.IsPolyline(line1[0]) or rs.CurveDegree(line1[0]) == 1 \
and not rs.IsCurveLinear(line1[0]):
flshPt= rs.AddPoint(line1[3])
rs.FlashObject(flshPt)
rs.DeleteObject(flshPt)
pLine(line1)
else:
line2 = rs.GetObjectEx('Pick another line')
rs.FlashObject(line2[0])
if rs.IsCurveLinear(line1[0]) and rs.IsCurveLinear(line2[0]):
twoLines(line1,line2)
else:
print 'REQUIRES 2 STRAIGHT LINES OR A SINGLE POLYLINE'
return
input()
if you like the idea of the script enough to re-write it properly… do that… i’d probably learn most that way
otherwise, some questions/complications:
1) when i did rs.CurveEditPoints, it returns
<Rhino.Collections.Point3dList object at 0x000000000000007E [Rhino.Collections.Point3dList]>
i didn’t know how to access the Rhino.Collections.Point3dList or what it meant (something to do with import Rhino?)
but, if i did this,
for i, items in enumerate(polyPts):
print i, items
…i could see inside
ended up doing the coerce3dpointlist thing since it gave me a list in a way i’m sort of used to seeing.
2)
since clicking a point at an end of a polyline will say the next point (which is needed for one vector) is the first in the list, i inserted another item into the list if a polyline endpoint was detected so the entire list would shift and the vertex would correspond with the proper index number of PointArrayClosestPoint.
however, i couldn’t do that with the start point of a list because it was saying the next index number in the list was -1…
or, the vertex was 0 and the two endpoints were -1 and 1… and i needed 0,1,2… so i ended up manually assigning if the point was near the start of a polyline but it seems like this could be done once for all three cases (inner angle, start of polyline and the end)
my question though is this- can you shift a list so the last item becomes the first then everything else moves accordingly?
3) i had this set up a bit better at first until during testing, i realized if you draw two lines then join them, they aren’t considered a polyline ??? so i had to do some stuff with the curve degree to sort through and this if statement became too long… if_or_and… is there a better way to break that down into simpler lines? like- one line is the if, one is the or, and one is the and?
thanks for any insight/wisdom/etc!!
[edit] i suppose this thing might fail in some circumstances with the PointArrayClosestPoint?? depending on the polyline, there might be a wrong vertex chosen since it’s closest to the pick point… i havne’t tested for it though… i’ll try it tomorrow… but if you see any other things that might break it, let me know.