/Scripts/rhinoscript/plane.py

http://github.com/mcneel/rhinopython · Python · 519 lines · 360 code · 25 blank · 134 comment · 33 complexity · bd032bd5ed76da25e04e67b56442461b MD5 · raw file

  1. import utility as rhutil
  2. import Rhino.Geometry
  3. import scriptcontext
  4. import math
  5. def DistanceToPlane(plane, point):
  6. """Returns the distance from a 3D point to a plane
  7. Parameters:
  8. plane (plane): the plane
  9. point (point): List of 3 numbers or Point3d
  10. Returns:
  11. number: The distance if successful, otherwise None
  12. Example:
  13. import rhinoscriptsyntax as rs
  14. point = rs.GetPoint("Point to test")
  15. if point:
  16. plane = rs.ViewCPlane()
  17. if plane:
  18. distance = rs.DistanceToPlane(plane, point)
  19. if distance is not None:
  20. print "Distance to plane: ", distance
  21. See Also:
  22. Distance
  23. PlaneClosestPoint
  24. """
  25. plane = rhutil.coerceplane(plane, True)
  26. point = rhutil.coerce3dpoint(point, True)
  27. return plane.DistanceTo(point)
  28. def EvaluatePlane(plane, parameter):
  29. """Evaluates a plane at a U,V parameter
  30. Parameters:
  31. plane (plane): the plane to evaluate
  32. parameter ([number, number]): list of two numbers defining the U,V parameter to evaluate
  33. Returns:
  34. point: Point3d on success
  35. Example:
  36. import rhinoscriptsyntax as rs
  37. view = rs.CurrentView()
  38. plane = rs.ViewCPlane(view)
  39. point = rs.EvaluatePlane(plane, (5,5))
  40. rs.AddPoint( point )
  41. See Also:
  42. PlaneClosestPoint
  43. """
  44. plane = rhutil.coerceplane(plane, True)
  45. return plane.PointAt(parameter[0], parameter[1])
  46. def IntersectPlanes(plane1, plane2, plane3):
  47. """Calculates the intersection of three planes
  48. Parameters:
  49. plane1 (plane): the 1st plane to intersect
  50. plane2 (plane): the 2nd plane to intersect
  51. plane3 (plane): the 3rd plane to intersect
  52. Returns:
  53. point: the intersection point between the 3 planes on success
  54. None: on error
  55. Example:
  56. import rhinoscriptsyntax as rs
  57. plane1 = rs.WorldXYPlane()
  58. plane2 = rs.WorldYZPlane()
  59. plane3 = rs.WorldZXPlane()
  60. point = rs.IntersectPlanes(plane1, plane2, plane3)
  61. if point: rs.AddPoint(point)
  62. See Also:
  63. LineLineIntersection
  64. LinePlaneIntersection
  65. PlanePlaneIntersection
  66. """
  67. plane1 = rhutil.coerceplane(plane1, True)
  68. plane2 = rhutil.coerceplane(plane2, True)
  69. plane3 = rhutil.coerceplane(plane3, True)
  70. rc, point = Rhino.Geometry.Intersect.Intersection.PlanePlanePlane(plane1, plane2, plane3)
  71. if rc: return point
  72. def MovePlane(plane, origin):
  73. """Moves the origin of a plane
  74. Parameters:
  75. plane (plane): Plane or ConstructionPlane
  76. origin (point): Point3d or list of three numbers
  77. Returns:
  78. plane: moved plane
  79. Example:
  80. import rhinoscriptsyntax as rs
  81. origin = rs.GetPoint("CPlane origin")
  82. if origin:
  83. plane = rs.ViewCPlane()
  84. plane = rs.MovePlane(plane,origin)
  85. rs.ViewCplane(plane)
  86. See Also:
  87. PlaneFromFrame
  88. PlaneFromNormal
  89. RotatePlane
  90. """
  91. plane = rhutil.coerceplane(plane, True)
  92. origin = rhutil.coerce3dpoint(origin, True)
  93. rc = Rhino.Geometry.Plane(plane)
  94. rc.Origin = origin
  95. return rc
  96. def PlaneClosestPoint(plane, point, return_point=True):
  97. """Returns the point on a plane that is closest to a test point.
  98. Parameters:
  99. plane (plane): The plane
  100. point (point): The 3-D point to test.
  101. return_point (bool, optional): If omitted or True, then the point on the plane
  102. that is closest to the test point is returned. If False, then the
  103. parameter of the point on the plane that is closest to the test
  104. point is returned.
  105. Returns:
  106. point: If return_point is omitted or True, then the 3-D point
  107. point: If return_point is False, then an array containing the U,V parameters
  108. of the point
  109. None: if not successful, or on error.
  110. Example:
  111. import rhinoscriptsyntax as rs
  112. point = rs.GetPoint("Point to test")
  113. if point:
  114. plane = rs.ViewCPlane()
  115. if plane:
  116. print rs.PlaneClosestPoint(plane, point)
  117. See Also:
  118. DistanceToPlane
  119. EvaluatePlane
  120. """
  121. plane = rhutil.coerceplane(plane, True)
  122. point = rhutil.coerce3dpoint(point, True)
  123. if return_point:
  124. return plane.ClosestPoint(point)
  125. else:
  126. rc, s, t = plane.ClosestParameter(point)
  127. if rc: return s, t
  128. def PlaneCurveIntersection(plane, curve, tolerance=None):
  129. """Intersect an infinite plane and a curve object
  130. Parameters:
  131. plane (plane): The plane to intersect.
  132. curve (guid): The identifier of the curve object
  133. torerance (number, optional): The intersection tolerance. If omitted, the document's absolute tolerance is used.
  134. Returns:
  135. A list of intersection information tuple if successful. The list will contain one or more of the following tuple:
  136. Element Type Description
  137. [0] Number The intersection event type, either Point (1) or Overlap (2).
  138. [1] Point3d If the event type is Point (1), then the intersection point on the curve.
  139. If the event type is Overlap (2), then intersection start point on the curve.
  140. [2] Point3d If the event type is Point (1), then the intersection point on the curve.
  141. If the event type is Overlap (2), then intersection end point on the curve.
  142. [3] Point3d If the event type is Point (1), then the intersection point on the plane.
  143. If the event type is Overlap (2), then intersection start point on the plane.
  144. [4] Point3d If the event type is Point (1), then the intersection point on the plane.
  145. If the event type is Overlap (2), then intersection end point on the plane.
  146. [5] Number If the event type is Point (1), then the curve parameter.
  147. If the event type is Overlap (2), then the start value of the curve parameter range.
  148. [6] Number If the event type is Point (1), then the curve parameter.
  149. If the event type is Overlap (2), then the end value of the curve parameter range.
  150. [7] Number If the event type is Point (1), then the U plane parameter.
  151. If the event type is Overlap (2), then the U plane parameter for curve at (n, 5).
  152. [8] Number If the event type is Point (1), then the V plane parameter.
  153. If the event type is Overlap (2), then the V plane parameter for curve at (n, 5).
  154. [9] Number If the event type is Point (1), then the U plane parameter.
  155. If the event type is Overlap (2), then the U plane parameter for curve at (n, 6).
  156. [10] Number If the event type is Point (1), then the V plane parameter.
  157. If the event type is Overlap (2), then the V plane parameter for curve at (n, 6).
  158. None: on error
  159. Example:
  160. import rhinoscriptsyntax as rs
  161. curve = rs.GetObject("Select curve", rs.filter.curve)
  162. if curve:
  163. plane = rs.WorldXYPlane()
  164. intersections = rs.PlaneCurveIntersection(plane, curve)
  165. if intersections:
  166. for intersection in intersections:
  167. rs.AddPoint(intersection[1])
  168. See Also:
  169. IntersectPlanes
  170. PlanePlaneIntersection
  171. PlaneSphereIntersection
  172. """
  173. plane = rhutil.coerceplane(plane, True)
  174. curve = rhutil.coercecurve(curve, -1, True)
  175. if tolerance is None: tolerance = scriptcontext.doc.ModelAbsoluteTolerance
  176. intersections = Rhino.Geometry.Intersect.Intersection.CurvePlane(curve, plane, tolerance)
  177. if intersections:
  178. rc = []
  179. for intersection in intersections:
  180. a = 1
  181. if intersection.IsOverlap: a = 2
  182. b = intersection.PointA
  183. c = intersection.PointA2
  184. d = intersection.PointB
  185. e = intersection.PointB2
  186. f = intersection.ParameterA
  187. g = intersection.ParameterB
  188. h = intersection.OverlapA[0]
  189. i = intersection.OverlapA[1]
  190. j = intersection.OverlapB[0]
  191. k = intersection.OverlapB[1]
  192. rc.append( (a,b,c,d,e,f,g,h,i,j,k) )
  193. return rc
  194. def PlaneEquation(plane):
  195. """Returns the equation of a plane as a tuple of four numbers. The standard
  196. equation of a plane with a non-zero vector is Ax+By+Cz+D=0
  197. Parameters:
  198. plane (plane): the plane to deconstruct
  199. Returns:
  200. tuple(number, number, number, number): containing four numbers that represent the coefficients of the equation (A, B, C, D) if successful
  201. None: if not successful
  202. Example:
  203. import rhinoscriptsyntax as rs
  204. plane = rs.ViewCPlane()
  205. equation = rs.PlaneEquation(plane)
  206. print "A =", equation[0]
  207. print "B =", equation[1]
  208. print "C =", equation[2]
  209. print "D =", equation[3]
  210. See Also:
  211. PlaneFromFrame
  212. PlaneFromNormal
  213. PlaneFromPoints
  214. """
  215. plane = rhutil.coerceplane(plane, True)
  216. rc = plane.GetPlaneEquation()
  217. return rc[0], rc[1], rc[2], rc[3]
  218. def PlaneFitFromPoints(points):
  219. """Returns a plane that was fit through an array of 3D points.
  220. Parameters:
  221. points (point): An array of 3D points.
  222. Returns:
  223. plane: The plane if successful
  224. None: if not successful
  225. Example:
  226. import rhinoscriptsyntax as rs
  227. points = rs.GetPoints()
  228. if points:
  229. plane = rs.PlaneFitFromPoints(points)
  230. if plane:
  231. magX = plane.XAxis.Length
  232. magY = plane.YAxis.Length
  233. rs.AddPlaneSurface( plane, magX, magY )
  234. See Also:
  235. PlaneFromFrame
  236. PlaneFromNormal
  237. PlaneFromPoints
  238. """
  239. points = rhutil.coerce3dpointlist(points, True)
  240. rc, plane = Rhino.Geometry.Plane.FitPlaneToPoints(points)
  241. if rc==Rhino.Geometry.PlaneFitResult.Success: return plane
  242. def PlaneFromFrame(origin, x_axis, y_axis):
  243. """Construct a plane from a point, and two vectors in the plane.
  244. Parameters:
  245. origin (point): A 3D point identifying the origin of the plane.
  246. x_axis (vector): A non-zero 3D vector in the plane that determines the X axis
  247. direction.
  248. y_axis (vector): A non-zero 3D vector not parallel to x_axis that is used
  249. to determine the Y axis direction. Note, y_axis does not
  250. have to be perpendicular to x_axis.
  251. Returns:
  252. plane: The plane if successful.
  253. Example:
  254. import rhinoscriptsyntax as rs
  255. origin = rs.GetPoint("CPlane origin")
  256. if origin:
  257. xaxis = (1,0,0)
  258. yaxis = (0,0,1)
  259. plane = rs.PlaneFromFrame( origin, xaxis, yaxis )
  260. rs.ViewCPlane(None, plane)
  261. See Also:
  262. MovePlane
  263. PlaneFromNormal
  264. PlaneFromPoints
  265. RotatePlane
  266. """
  267. origin = rhutil.coerce3dpoint(origin, True)
  268. x_axis = rhutil.coerce3dvector(x_axis, True)
  269. y_axis = rhutil.coerce3dvector(y_axis, True)
  270. return Rhino.Geometry.Plane(origin, x_axis, y_axis)
  271. def PlaneFromNormal(origin, normal, xaxis=None):
  272. """Creates a plane from an origin point and a normal direction vector.
  273. Parameters:
  274. origin (point): A 3D point identifying the origin of the plane.
  275. normal (vector): A 3D vector identifying the normal direction of the plane.
  276. xaxis (vector, optional): optional vector defining the plane's x-axis
  277. Returns:
  278. plane: The plane if successful.
  279. Example:
  280. import rhinoscriptsyntax as rs
  281. origin = rs.GetPoint("CPlane origin")
  282. if origin:
  283. direction = rs.GetPoint("CPlane direction")
  284. if direction:
  285. normal = direction - origin
  286. normal = rs.VectorUnitize(normal)
  287. rs.ViewCPlane( None, rs.PlaneFromNormal(origin, normal) )
  288. See Also:
  289. MovePlane
  290. PlaneFromFrame
  291. PlaneFromPoints
  292. RotatePlane
  293. """
  294. origin = rhutil.coerce3dpoint(origin, True)
  295. normal = rhutil.coerce3dvector(normal, True)
  296. rc = Rhino.Geometry.Plane(origin, normal)
  297. if xaxis:
  298. xaxis = rhutil.coerce3dvector(xaxis, True)
  299. xaxis = Rhino.Geometry.Vector3d(xaxis)#prevent original xaxis parameter from being unitized too
  300. xaxis.Unitize()
  301. yaxis = Rhino.Geometry.Vector3d.CrossProduct(rc.Normal, xaxis)
  302. rc = Rhino.Geometry.Plane(origin, xaxis, yaxis)
  303. return rc
  304. def PlaneFromPoints(origin, x, y):
  305. """Creates a plane from three non-colinear points
  306. Parameters:
  307. origin (point): origin point of the plane
  308. x, y (point): points on the plane's x and y axes
  309. Returns:
  310. plane: The plane if successful, otherwise None
  311. Example:
  312. import rhinoscriptsyntax as rs
  313. corners = rs.GetRectangle()
  314. if corners:
  315. rs.ViewCPlane( rs.PlaneFromPoints(corners[0], corners[1], corners[3]))
  316. See Also:
  317. PlaneFromFrame
  318. PlaneFromNormal
  319. """
  320. origin = rhutil.coerce3dpoint(origin, True)
  321. x = rhutil.coerce3dpoint(x, True)
  322. y = rhutil.coerce3dpoint(y, True)
  323. plane = Rhino.Geometry.Plane(origin, x, y)
  324. if plane.IsValid: return plane
  325. def PlanePlaneIntersection(plane1, plane2):
  326. """Calculates the intersection of two planes
  327. Parameters:
  328. plane1 (plane): the 1st plane to intersect
  329. plane2 (plane): the 2nd plane to intersect
  330. Returns:
  331. line: a line with two 3d points identifying the starting/ending points of the intersection
  332. None: on error
  333. Example:
  334. import rhinoscriptsyntax as rs
  335. plane1 = rs.WorldXYPlane()
  336. plane2 = rs.WorldYZPlane()
  337. line = rs.PlanePlaneIntersection(plane1, plane2)
  338. if line: rs.AddLine(line[0], line[1])
  339. See Also:
  340. IntersectPlanes
  341. LineLineIntersection
  342. LinePlaneIntersection
  343. """
  344. plane1 = rhutil.coerceplane(plane1, True)
  345. plane2 = rhutil.coerceplane(plane2, True)
  346. rc, line = Rhino.Geometry.Intersect.Intersection.PlanePlane(plane1, plane2)
  347. if rc: return line.From, line.To
  348. def PlaneSphereIntersection(plane, sphere_plane, sphere_radius):
  349. """Calculates the intersection of a plane and a sphere
  350. Parameters:
  351. plane (plane): the plane to intersect
  352. sphere_plane (plane): equatorial plane of the sphere. origin of the plane is
  353. the center of the sphere
  354. sphere_radius (number): radius of the sphere
  355. Returns:
  356. list(number, point|plane, number): of intersection results
  357. Element Type Description
  358. [0] number The type of intersection, where 0 = point and 1 = circle.
  359. [1] point or plane If a point intersection, the a Point3d identifying the 3-D intersection location.
  360. If a circle intersection, then the circle's plane. The origin of the plane will be the center point of the circle
  361. [2] number If a circle intersection, then the radius of the circle.
  362. None: on error
  363. Example:
  364. import rhinoscriptsyntax as rs
  365. plane = rs.WorldXYPlane()
  366. radius = 10
  367. results = rs.PlaneSphereIntersection(plane, plane, radius)
  368. if results:
  369. if results[0]==0:
  370. rs.AddPoint(results[1])
  371. else:
  372. rs.AddCircle(results[1], results[2])
  373. See Also:
  374. IntersectPlanes
  375. LinePlaneIntersection
  376. PlanePlaneIntersection
  377. """
  378. plane = rhutil.coerceplane(plane, True)
  379. sphere_plane = rhutil.coerceplane(sphere_plane, True)
  380. sphere = Rhino.Geometry.Sphere(sphere_plane, sphere_radius)
  381. rc, circle = Rhino.Geometry.Intersect.Intersection.PlaneSphere(plane, sphere)
  382. if rc==Rhino.Geometry.Intersect.PlaneSphereIntersection.Point:
  383. return 0, circle.Center
  384. if rc==Rhino.Geometry.Intersect.PlaneSphereIntersection.Circle:
  385. return 1, circle.Plane, circle.Radius
  386. def PlaneTransform(plane, xform):
  387. """Transforms a plane
  388. Parameters:
  389. plane (plane): Plane to transform
  390. xform (transform): Transformation to apply
  391. Returns:
  392. plane:the resulting plane if successful
  393. None: if not successful
  394. Example:
  395. import rhinoscriptsyntax as rs
  396. plane = rs.ViewCPlane()
  397. xform = rs.XformRotation(45.0, plane.Zaxis, plane.Origin)
  398. plane = rs.PlaneTransform(plane, xform)
  399. rs.ViewCPlane(None, plane)
  400. See Also:
  401. PlaneFromFrame
  402. PlaneFromNormal
  403. PlaneFromPoints
  404. """
  405. plane = rhutil.coerceplane(plane, True)
  406. xform = rhutil.coercexform(xform, True)
  407. rc = Rhino.Geometry.Plane(plane)
  408. if rc.Transform(xform): return rc
  409. def RotatePlane(plane, angle_degrees, axis):
  410. """Rotates a plane
  411. Parameters:
  412. plane (plane): Plane to rotate
  413. angle_degrees (number): rotation angle in degrees
  414. axis (vector): Axis of rotation or list of three numbers
  415. Returns:
  416. plane: rotated plane on success
  417. Example:
  418. import rhinoscriptsyntax as rs
  419. plane = rs.ViewCPlane()
  420. rotated = rs.RotatePlane(plane, 45.0, plane.XAxis)
  421. rs.ViewCPlane( None, rotated )
  422. See Also:
  423. MovePlane
  424. PlaneFromFrame
  425. PlaneFromNormal
  426. """
  427. plane = rhutil.coerceplane(plane, True)
  428. axis = rhutil.coerce3dvector(axis, True)
  429. angle_radians = math.radians(angle_degrees)
  430. rc = Rhino.Geometry.Plane(plane)
  431. if rc.Rotate(angle_radians, axis): return rc
  432. def WorldXYPlane():
  433. """Returns Rhino's world XY plane
  434. Returns:
  435. plane: Rhino's world XY plane
  436. Example:
  437. import rhinoscriptsyntax as rs
  438. view = rs.CurrentView()
  439. rs.ViewCPlane( view, rs.WorldXYPlane() )
  440. See Also:
  441. WorldYZPlane
  442. WorldZXPlane
  443. """
  444. return Rhino.Geometry.Plane.WorldXY
  445. def WorldYZPlane():
  446. """Returns Rhino's world YZ plane
  447. Returns:
  448. plane: Rhino's world YZ plane
  449. Example:
  450. import rhinoscriptsyntax as rs
  451. view = rs.CurrentView()
  452. rs.ViewCPlane( view, rs.WorldYZPlane() )
  453. See Also:
  454. WorldXYPlane
  455. WorldZXPlane
  456. """
  457. return Rhino.Geometry.Plane.WorldYZ
  458. def WorldZXPlane():
  459. """Returns Rhino's world ZX plane
  460. Returns:
  461. plane: Rhino's world ZX plane
  462. Example:
  463. import rhinoscriptsyntax as rs
  464. view = rs.CurrentView()
  465. rs.ViewCPlane( view, rs.WorldZXPlane() )
  466. See Also:
  467. WorldXYPlane
  468. WorldYZPlane
  469. """
  470. return Rhino.Geometry.Plane.WorldZX