Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Rhino
- import clr
- clr.AddReferenceToFile("KangarooSolver.dll")
- import KangarooSolver as ks
- from System import Array, Double
- class PolygonArea(ks.GoalObject):
- def __init__(self, polyline, area, strength=1):
- P = [polyline[i] for i in range(len(polyline)-1 if polyline.IsClosed else len(polyline))]
- self.PPos = Array[Rhino.Geometry.Point3d](P)
- self.Move = Array.CreateInstance(Rhino.Geometry.Vector3d, len(P))
- self.Weighting = Array[Double]([strength] * len(P))
- self.Strength = strength
- self.TargetArea = area
- def Calculate(self, p):
- Array.Clear(self.Move, 0, self.Move.Length)
- Array.Clear(self.Weighting, 0, self.Weighting.Length)
- xfpts = [Rhino.Geometry.Point3d(p[self.PIndex[i]].Position) for i in range(self.PIndex.Length)]
- pfresult, plane = Rhino.Geometry.Plane.FitPlaneToPoints(xfpts)
- if pfresult == Rhino.Geometry.PlaneFitResult.Failure:
- raise RuntimeError("Couldn't fit plane to points")
- xform = Rhino.Geometry.Transform.ChangeBasis(Rhino.Geometry.Plane.WorldXY, plane)
- for pt in xfpts:
- pt.Transform(xform)
- areadoubled = 0
- totallength = 0
- L = self.PIndex.Length
- for i in range(L):
- p1, p2 = xfpts[i], xfpts[(i+1)%L]
- areadoubled += Rhino.Geometry.Vector3d.CrossProduct(
- Rhino.Geometry.Vector3d(p1),
- Rhino.Geometry.Vector3d(p2)).Z
- totallength += p1.DistanceTo(p2)
- normal = plane.Normal
- if areadoubled < 0:
- areadoubled *= -1
- normal *= -1
- areashortage = self.TargetArea - 0.5 * areadoubled
- offset = areashortage / totallength
- for i in range(L):
- nexti = (i+1) % L
- edge = p[self.PIndex[nexti]].Position - p[self.PIndex[i]].Position
- edge.Unitize()
- pressure = offset * Rhino.Geometry.Vector3d.CrossProduct(edge, normal)
- self.Move[i] += pressure
- self.Move[nexti] += pressure
- self.Weighting[i] = self.Strength
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement