Site Tools


Arc Point Distribution

Developer: RhinoScript
Summary: Discusses arc point distribution.

Question

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?

Answer

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()



developer/scriptsamples/arcpointdistribution.txt ยท Last modified: 2015/09/14 (external edit)