Developer: RhinoScript
Summary: Discusses arc point distribution.
I have have a series of points that are equally spaced along an arc curve. I would like these points projected onto the line that connects the starting and ending points of the arc. For example:
Is there a way that I can do this mathematically, or do I have to do some kind of projection or intersection?
The following example script should do what you want.
RhinoScript
Option Explicit Sub ArcPointDistribution ' Local variables Dim arc, cnt, rads Dim n_t(), n, i, a0, a1 Dim line, dom, t ' Select arc curve arc = Rhino.GetObject("Select arc", 4) If IsNull(arc) Then Exit Sub If Not Rhino.IsArc(arc) Then Exit Sub ' Get number of points to calculate cnt = Rhino.GetInteger("Number of points", 2) If IsNull(cnt) Then Exit Sub rads = Rhino.ToRadians(Rhino.ArcAngle(arc)) n = cnt - 1 ReDim n_t(n) ' Calculate normalized parameters For i = 0 To n a0 = Sin(rads/2) a1 = Sin(i*rads/n - rads/2) n_t(i) = (a0+a1)/(2*a0) Next Rhino.EnableRedraw False line = Rhino.AddLine(Rhino.CurveStartPoint(arc), Rhino.CurveEndPoint(arc)) dom = Rhino.CurveDomain(line) For i = 0 To n ' Convert normalized parameter to domain value t = (1.0 - n_t(i)) * dom(0) + n_t(i) * dom(1) Rhino.AddPoint Rhino.EvaluateCurve(line, t) Next Rhino.EnableRedraw True End Sub
Python
import rhinoscriptsyntax as rs import math def ArcPointDistribution(): # Select arc curve arc = rs.GetObject("Select arc", rs.filter.curve) if not arc or not rs.IsArc(arc): return # Get number of points to calculate count = rs.GetInteger("Number of points", 2, 1) if count is None or count<2: return rads = math.radians(rs.ArcAngle(arc)) n_t = [] # Calculate normalized parameters for i in range(count): a0 = math.sin(rads/2) a1 = math.sin(i*rads/(count-1) - rads/2) n_t.append( (a0+a1)/(2*a0) ) rs.EnableRedraw(False) line = rs.AddLine(rs.CurveStartPoint(arc), rs.CurveEndPoint(arc)) dom = rs.CurveDomain(line) for i in range(count): # Convert normalized parameter to domain value t = (1.0 - n_t[i]) * dom[0] + n_t[i] * dom[1] rs.AddPoint( rs.EvaluateCurve(line,t) ) rs.EnableRedraw(True) if __name__=="__main__": ArcPointDistribution()