def drawOpening(distance, length, block=0): if block == 1 and rs.IsBlock("window") == False: util.initWindowBlock() if block == 2 and rs.IsBlock("door") == False: util.initDoorBlock() if not rs.IsLayer("Axis"): util.initCaadLayer("Axis") twoLines = findTwoParallelLines() if not twoLines: return 0 pi, linei, linej = twoLines if not linej: return 0 pj = linej.CurveGeometry.Line.ClosestPoint(pi, False) oldLockMode = rs.LayerLocked("Axis", True) # side=0 start from startPoint , side=1 start from endPoint if rs.Distance(linei.CurveGeometry.Line.From, pi) <= rs.Distance( pi, linei.CurveGeometry.Line.To): side = 0 else: side = 1 # direct: # 0 | 1 # ------- # 2 | 3 vji = rs.VectorCreate(pj, pi) vi = linei.CurveGeometry.Line.Direction angle = rs.Angle((0, 0, 0), rs.VectorRotate(vji, -rs.Angle((0, 0, 0), vi)[0], (0, 0, 1))) if abs(angle[0] - 90) < sc.doc.ModelAbsoluteTolerance: line0 = linei line1 = linej if side == 0: direct = 2 else: direct = 3 elif abs(angle[0] + 90) < sc.doc.ModelAbsoluteTolerance: line0 = linej line1 = linei if side == 0: direct = 0 else: direct = 1 dl = DoubleLine(line0.CurveGeometry.Line, line1.CurveGeometry.Line) newLayer = rs.ObjectLayer(line0.Id) oldLayer = rs.CurrentLayer(newLayer) dl.drawOpening(distance, length, side, block, direct) rs.DeleteObject(line0.Id) rs.DeleteObject(line1.Id) rs.CurrentLayer(oldLayer) rs.LayerLocked("Axis", oldLockMode)
def drawIntersectionWithDoubleLine(self, doubleLine): """draw two doubleLines: selfDoubleLine and antherDoubleLine a=selfDoubleLine Type: System.Double Parameter on self.line0 that is closest to doubeLine.line0. ab > 1 : means outside of self.line0.To ab < 0 : means outside of self.line0.From 0 <=ab<= 1 : means inside of self.line0 b=anotherDoubleLine Type: System.Double Parameter on doubleLine.line0 that is closest to self.line0. ba > 1 : means outside of doubleLine.line0.To ba < 0 : means outside of doubleLine.line0.From 0<= ba <= 1 : means inside of doubleLine.line0 angle Type: System.Double counterclockwise angle between self and another """ #get intersection infomation between two doubleLines rc, a0b0, b0a0 = geo.Intersect.Intersection.LineLine( self.line0, doubleLine.line0) if not rc: print "Parallel doubleLine found." return (False, None, None) rc, a0b1, b1a0 = geo.Intersect.Intersection.LineLine( self.line0, doubleLine.line1) rc, a1b0, b0a1 = geo.Intersect.Intersection.LineLine( self.line1, doubleLine.line0) rc, a1b1, b1a1 = geo.Intersect.Intersection.LineLine( self.line1, doubleLine.line1) # self.direction, doubleLine.direction angle = rs.Angle( (0, 0, 0), rs.VectorRotate(doubleLine.direction, -rs.Angle( (0, 0, 0), self.direction)[0], (0, 0, 1))) selfRawParameter = ((a0b0, a0b1, a1b0, a1b1, b0a0, b1a0, b0a1, b1a1), -angle[0]) anotherRawParameter = ((b0a0, b0a1, b1a0, b1a1, a0b0, a1b0, a0b1, a1b1), angle[0]) # ----self-doubleLine-a---- selfParam = self._getDoubleLineParameterByIntersection( selfRawParameter) # ----another-doubleLine-b--- anotherParam = doubleLine._getDoubleLineParameterByIntersection( anotherRawParameter) # ----draw self-doubleLine-a---- self.drawDoubleLineByparameterList(selfParam[0], selfParam[1]) # ----draw another-doubleLine-b--- doubleLine.drawDoubleLineByparameterList(anotherParam[0], anotherParam[1])
def findAngle(self, positionA, positionB): """ positionA : x and y coordinates of a turtle positionB : x and y coordinates of a turtle """ angle = rs.Angle(positionA, positionB) return angle[0]
def solveequation( function, x, y ): d = rs.Hypot(x,y) angledata = rs.Angle( (0,0,0), (x,y,0)) a = 0.0 if angledata: a = math.radians(angledata[0]) z = eval(function) return z
def __init__(self, line0, line1): # initialized by two Rhino.Geometry.Line self.isDoubleLine = True self.direction = None self.line0 = None self.line1 = None self.width = 0 direction0 = rs.VectorUnitize(line0.Direction) self.direction = direction0 # not parallel if rs.IsVectorParallelTo(direction0, rs.VectorUnitize(line1.Direction)) == 0: self.isDoubleLine = False else: # parallel but in oppersite direction if rs.IsVectorParallelTo(direction0, rs.VectorUnitize(line1.Direction)) == -1: line1.Flip() # find the closest point to line1's start point line0ClosePoint = line0.ClosestPoint(line1.From, False) vector = rs.VectorCreate(line1.From, line0ClosePoint) distance = rs.Distance(line1.From, line0ClosePoint) if distance >= config.DOUBLELINEWIDTHLIMIT[ 0] and distance <= config.DOUBLELINEWIDTHLIMIT[1]: self.width = distance angle = rs.Angle( (0, 0, 0), rs.VectorRotate(vector, -rs.Angle(line0.From, line0.To)[0], (0, 0, 1))) if abs(angle[0] - 90) < sc.doc.ModelAbsoluteTolerance: self.line0 = line1 self.line1 = line0 elif abs(angle[0] + 90) < sc.doc.ModelAbsoluteTolerance: self.line0 = line0 self.line1 = line1
def drawOpening(self, distance, length, side=0, block=0, direct=0): """ side=0 start from startPoint , side=1 start from endPoint direct: 0 | 1 ------- 2 | 3 block 0=empty 1=window 2=door """ localDirect = direct if side == 1: self.flip() if direct == 0: localDirect = 3 if direct == 1: localDirect = 2 if direct == 2: localDirect = 1 if direct == 3: localDirect = 0 startParameter = self.line1.ClosestParameter(self.line0.From) startPoint = self.line1.ClosestPoint(self.line0.From, False) if startParameter >= 0: distance00 = distance distance10 = distance + startPoint.DistanceTo(self.line1.From) else: distance00 = distance + startPoint.DistanceTo(self.line1.From) distance10 = distance distance01 = distance00 + length distance11 = distance10 + length """ p10 p11 ------ ------>line1 | | ------ ------>line0 p00 p01 """ point00 = self.line0.PointAtLength(distance00) point10 = self.line1.PointAtLength(distance10) point01 = self.line0.PointAtLength(distance01) point11 = self.line1.PointAtLength(distance11) parameter00 = self.line0.ClosestParameter(point00) parameter10 = self.line1.ClosestParameter(point10) parameter01 = self.line0.ClosestParameter(point01) parameter11 = self.line1.ClosestParameter(point11) if parameter00 < 0 or parameter00 > 1 or parameter10 < 0 or parameter10 > 1 or parameter01 < 0 or parameter01 > 1 or parameter11 < 0 or parameter11 > 1: print("error: wrong opening length") return 0 # drawing sc.doc.Objects.AddLine(point00, point10) sc.doc.Objects.AddLine(point01, point11) sc.doc.Objects.AddLine(self.line0.From, self.line0.PointAt(parameter00)) sc.doc.Objects.AddLine(self.line0.PointAt(parameter01), self.line0.To) sc.doc.Objects.AddLine(self.line1.From, self.line1.PointAt(parameter10)) sc.doc.Objects.AddLine(self.line1.PointAt(parameter11), self.line1.To) # empty if block == 0: pass # window elif block == 1: scaleX = point00.DistanceTo(point01) / 1000 scaleY = point00.DistanceTo(point10) / 100 origin = (point00 + point10 + point01 + point11) / 4 block_id = rs.InsertBlock("window", origin, (scaleX, scaleY, 1), 0, (0, 0, 1)) angle_degrees = rs.Angle(point00, point01)[0] rs.RotateObject(block_id, origin, angle_degrees) # door elif block == 2: scaleX = point00.DistanceTo(point01) / 1000 scaleY = scaleX origin = (point00 + point10 + point01 + point11) / 4 block_id = rs.InsertBlock("door", origin, (scaleX, scaleY, 1), 0, (0, 0, 1)) angle_degrees = rs.Angle(point00, point01)[0] rs.RotateObject(block_id, origin, angle_degrees) if localDirect == 0: pass elif localDirect == 1: rs.MirrorObject(block_id, (point10 + point11) / 2, (point00 + point01) / 2) elif localDirect == 2: rs.MirrorObject(block_id, (point00 + point10) / 2, (point01 + point11) / 2) elif localDirect == 3: rs.MirrorObject(block_id, (point10 + point11) / 2, (point00 + point01) / 2) rs.MirrorObject(block_id, (point00 + point10) / 2, (point01 + point11) / 2)
def SampleGardenPath(): # Acquire information for the garden path start_point = rs.GetPoint('Start point of path') if start_point is None: return end_point = rs.GetPoint('End point of path', start_point) if end_point is None: return half_width = rs.GetDistance(start_point, None, 'First width point', 'Half width of path') if half_width is None: return tile_radius = rs.GetReal('Radius of tiles', 1.0) if tile_radius is None: return if tile_radius <= 0.0: return tile_spacing = rs.GetReal('Distance between tiles', 1.0) if tile_spacing is None: return if tile_spacing < 0.0: return # To increase speed, disable redrawing rs.EnableRedraw(False) # Calculate angles angle_rc = rs.Angle(start_point, end_point) angle = angle_rc[0] length = rs.Distance(start_point, end_point) width = half_width * 2 angle_p90 = angle + 90.0 angle_m90 = angle - 90.0 # Draw the outline of the path polyline = [] polyline.append(rs.Polar(start_point, angle_m90, half_width)) polyline.append(rs.Polar(polyline[0], angle, length)) polyline.append(rs.Polar(polyline[1], angle_p90, width)) polyline.append(rs.Polar(polyline[2], angle + 180.0, length)) polyline.append(polyline[0]) rs.AddPolyline(polyline) # Draw the rows of tiles plane = rs.WorldXYPlane() distance = tile_radius + tile_spacing offset = 0.0 while (distance <= length - tile_radius): # Place one row of tiles given polyline along path and possibly offset it first = rs.Polar(start_point, angle, distance) current = rs.Polar(first, angle_p90, offset) next = current while (rs.Distance(first, next) < half_width - tile_radius): plane = rs.MovePlane(plane, next) rs.AddCircle(plane, tile_radius) next = rs.Polar(next, angle_p90, tile_spacing + tile_radius + tile_radius) next = rs.Polar(current, angle_m90, tile_spacing + tile_radius + tile_radius) while (rs.Distance(first, next) < half_width - tile_radius): plane = rs.MovePlane(plane, next) rs.AddCircle(plane, tile_radius) next = rs.Polar(next, angle_m90, tile_spacing + tile_radius + tile_radius) distance = distance + ((tile_spacing + tile_radius + tile_radius) * math.sin(60.0 * 180.0 / math.pi)) if (offset == 0.0): offset = (tile_spacing + tile_radius + tile_radius) * math.cos( 60.0 * 180.0 / math.pi) else: offset = 0.0 rs.EnableRedraw(True)
def test(): #Assign variables to the sin and cos functions for use later. Sin = math.sin Cos = math.cos # Acquire information for the garden path # set default values for the distances default_hwidth = 1 default_trad = 1 default_tspace = 1 # look for any previously used values stored in sticky and use those if available. if sc.sticky.has_key("GP_WIDTH"): default_hwidth = sc.sticky["GP_WIDTH"] if sc.sticky.has_key("GP_RAD"): default_trad = sc.sticky["GP_RAD"] if sc.sticky.has_key("GP_Space"): default_tspace = sc.sticky["GP_SPACE"] #get the path direction, length and location from two points entered by the user sp = rs.GetPoint("Start point of path centerline") if sp is None: return ep = rs.GetPoint("End point of path centerline", sp) if ep is None: return #now ask the user what the distances should be, offering the defaults arrived at above hwidth = rs.GetDistance(sp, default_hwidth, second_pt_msg="Half width of path") if hwidth is None: return #Store the new value in sticky for use next time sc.sticky["GP_WIDTH"] = hwidth trad = rs.GetDistance(sp, default_trad, second_pt_msg="Radius of tiles") if trad is None: return #Store the new value in sticky for use next time sc.sticky["GP_RAD"] = trad tspace = rs.GetDistance(sp, default_tspace, second_pt_msg="Distance between tiles") if tspace is None: return #Store the new value in sticky for use next time sc.sticky["GP_SPACE"] = tspace # Calculate angles temp = rs.Angle(sp, ep) pangle = temp[0] plength = rs.Distance(sp, ep) width = hwidth * 2 angp90 = pangle + 90.0 angm90 = pangle - 90.0 # To increase speed, disable redrawing rs.EnableRedraw(False) # Draw the outline of the path #make an empty list pline = [] #add points to the list pline.append(rs.Polar(sp, angm90, hwidth)) pline.append(rs.Polar(pline[0], pangle, plength)) pline.append(rs.Polar(pline[1], angp90, width)) pline.append(rs.Polar(pline[2], pangle + 180.0, plength)) #add the first point back on to the end of the list to close the pline pline.append(pline[0]) #create the polyline from the lst of points. rs.AddPolyline(pline) # Draw the rows of tiles #define a plane - #using the WorldXY plane the reults will always be added parallel to that plane, #regardless of the active plane where the points are picked. plane = rs.WorldXYPlane() pdist = trad + tspace off = 0.0 while (pdist <= plength - trad): #Place one row of tiles given distance along path # and possibly offset it pfirst = rs.Polar(sp, pangle, pdist) pctile = rs.Polar(pfirst, angp90, off) pltile = pctile while (rs.Distance(pfirst, pltile) < hwidth - trad): plane = rs.MovePlane(plane, pltile) rs.AddCircle(plane, trad) pltile = rs.Polar(pltile, angp90, tspace + trad + trad) pltile = rs.Polar(pctile, angm90, tspace + trad + trad) while (rs.Distance(pfirst, pltile) < hwidth - trad): plane = rs.MovePlane(plane, pltile) rs.AddCircle(plane, trad) pltile = rs.Polar(pltile, angm90, tspace + trad + trad) pdist = pdist + ((tspace + trad + trad) * Sin(math.radians(60))) if off == 0.0: off = (tspace + trad + trad) * Cos(math.radians(60)) else: off = 0.0
import rhinoscriptsyntax as rs from Rhino.Geometry import Point3d, Vector3d #lines = rs.GetObjects("Select lines", filter=4) lines = rs.AllObjects() for i in range(len(lines)): p = Point3d(i, 0, 0) v = p - rs.CurveStartPoint(lines[i]) rs.TransformObject(lines[i], rs.XformTranslation(v)) a = rs.Angle(rs.CurveStartPoint(lines[i]), rs.CurveEndPoint(lines[i]))[0] rs.TransformObject(lines[i], rs.XformRotation2(90 - a, Vector3d.ZAxis, p)) start = 1 while start < len(lines): current = start while current > 0 and rs.CurveLength(lines[current - 1]) > rs.CurveLength( lines[current]): rs.TransformObject(lines[current], rs.XformTranslation((-1, 0, 0))) rs.TransformObject(lines[current - 1], rs.XformTranslation((1, 0, 0))) lines[current], lines[current - 1] = lines[current - 1], lines[current] current -= 1 rs.Sleep(500) start += 1