Advertisement
Guest User

planefit PolygonArea v2

a guest
Dec 8th, 2018
120
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.13 KB | None | 0 0
  1. import Rhino
  2. import clr
  3. clr.AddReferenceToFile("KangarooSolver.dll")
  4. import KangarooSolver as ks
  5. from System import Array, Double
  6.  
  7. class PolygonArea(ks.GoalObject):
  8.     def __init__(self, polyline, area, strength=1):
  9.         P = [polyline[i] for i in range(len(polyline)-1 if polyline.IsClosed else len(polyline))]
  10.         self.PPos = Array[Rhino.Geometry.Point3d](P)
  11.         self.Move = Array.CreateInstance(Rhino.Geometry.Vector3d, len(P))
  12.         self.Weighting = Array[Double]([strength] * len(P))
  13.         self.Strength = strength
  14.         self.TargetArea = area
  15.  
  16.     def Calculate(self, p):
  17.         Array.Clear(self.Move, 0, self.Move.Length)
  18.         Array.Clear(self.Weighting, 0, self.Weighting.Length)
  19.  
  20.         xfpts = [Rhino.Geometry.Point3d(p[self.PIndex[i]].Position) for i in range(self.PIndex.Length)]
  21.         pfresult, plane = Rhino.Geometry.Plane.FitPlaneToPoints(xfpts)
  22.         if pfresult == Rhino.Geometry.PlaneFitResult.Failure:
  23.             raise RuntimeError("Couldn't fit plane to points")
  24.  
  25.         xform = Rhino.Geometry.Transform.ChangeBasis(Rhino.Geometry.Plane.WorldXY, plane)
  26.         for pt in xfpts:
  27.             pt.Transform(xform)
  28.  
  29.         areadoubled = 0
  30.         totallength = 0
  31.         L = self.PIndex.Length
  32.         for i in range(L):
  33.             p1, p2 = xfpts[i], xfpts[(i+1)%L]
  34.             areadoubled += Rhino.Geometry.Vector3d.CrossProduct(
  35.                 Rhino.Geometry.Vector3d(p1),
  36.                 Rhino.Geometry.Vector3d(p2)).Z
  37.             totallength += p1.DistanceTo(p2)
  38.            
  39.         normal = plane.Normal
  40.         if areadoubled < 0:
  41.             areadoubled *= -1
  42.             normal *= -1
  43.            
  44.         areashortage = self.TargetArea - 0.5 * areadoubled
  45.         offset = areashortage / totallength
  46.  
  47.         for i in range(L):
  48.             nexti = (i+1) % L
  49.             edge = p[self.PIndex[nexti]].Position - p[self.PIndex[i]].Position
  50.             edge.Unitize()
  51.             pressure = offset * Rhino.Geometry.Vector3d.CrossProduct(edge, normal)
  52.             self.Move[i] += pressure
  53.             self.Move[nexti] += pressure
  54.             self.Weighting[i] = self.Strength
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement