fbpx
Wikipedia

Centripetal Catmull–Rom spline

In computer graphics, the centripetal Catmull–Rom spline is a variant form of the Catmull–Rom spline, originally formulated by Edwin Catmull and Raphael Rom,[1] which can be evaluated using a recursive algorithm proposed by Barry and Goldman.[2] It is a type of interpolating spline (a curve that goes through its control points) defined by four control points , with the curve drawn only from to .

Catmull–Rom spline interpolation with four points

Definition edit

 
Barry and Goldman's pyramidal formulation
 
Knot parameterization for the Catmull–Rom algorithm

Let   denote a point. For a curve segment   defined by points   and knot sequence  , the centripetal Catmull–Rom spline can be produced by:

 

where

 
 
 
 
 

and

 

in which   ranges from 0 to 1 for knot parameterization, and   with  . For centripetal Catmull–Rom spline, the value of   is  . When  , the resulting curve is the standard uniform Catmull–Rom spline; when  , the result is a chordal Catmull–Rom spline.

 
Gif animation for uniform, centripetal and chordal parameterization of Catmull–Rom spline depending on the α value

Plugging   into the spline equations   and   shows that the value of the spline curve at   is  . Similarly, substituting   into the spline equations shows that   at  . This is true independent of the value of   since the equation for   is not needed to calculate the value of   at points   and  .

 
3D centripetal Catmull-Rom spline segment.

The extension to 3D points is simply achieved by considering  a generic 3D point   and

 

Advantages edit

Centripetal Catmull–Rom spline has several desirable mathematical properties compared to the original and the other types of Catmull-Rom formulation.[3] First, it will not form loop or self-intersection within a curve segment. Second, cusp will never occur within a curve segment. Third, it follows the control points more tightly.[4][vague]

 
In this figure, there is a self-intersection/loop on the uniform Catmull-Rom spline (green), whereas for chordal Catmull-Rom spline (red), the curve does not follow tightly through the control points.

Other uses edit

In computer vision, centripetal Catmull-Rom spline has been used to formulate an active model for segmentation. The method is termed active spline model.[5] The model is devised on the basis of active shape model, but uses centripetal Catmull-Rom spline to join two successive points (active shape model uses simple straight line), so that the total number of points necessary to depict a shape is less. The use of centripetal Catmull-Rom spline makes the training of a shape model much simpler, and it enables a better way to edit a contour after segmentation.

Code example in Python edit

The following is an implementation of the Catmull–Rom spline in Python that produces the plot shown beneath.

import numpy import matplotlib.pyplot as plt QUADRUPLE_SIZE: int = 4 def num_segments(point_chain: tuple) -> int: # There is 1 segment per 4 points, so we must subtract 3 from the number of points  return len(point_chain) - (QUADRUPLE_SIZE - 1) def flatten(list_of_lists) -> list: # E.g. mapping [[1, 2], [3], [4, 5]] to [1, 2, 3, 4, 5]  return [elem for lst in list_of_lists for elem in lst] def catmull_rom_spline( P0: tuple, P1: tuple, P2: tuple, P3: tuple, num_points: int, alpha: float = 0.5, ):  """  Compute the points in the spline segment  :param P0, P1, P2, and P3: The (x,y) point pairs that define the Catmull-Rom spline  :param num_points: The number of points to include in the resulting curve segment  :param alpha: 0.5 for the centripetal spline, 0.0 for the uniform spline, 1.0 for the chordal spline.  :return: The points  """ # Calculate t0 to t4. Then only calculate points between P1 and P2. # Reshape linspace so that we can multiply by the points P0 to P3 # and get a point for each value of t. def tj(ti: float, pi: tuple, pj: tuple) -> float: xi, yi = pi xj, yj = pj dx, dy = xj - xi, yj - yi l = (dx ** 2 + dy ** 2) ** 0.5 return ti + l ** alpha t0: float = 0.0 t1: float = tj(t0, P0, P1) t2: float = tj(t1, P1, P2) t3: float = tj(t2, P2, P3) t = numpy.linspace(t1, t2, num_points).reshape(num_points, 1) A1 = (t1 - t) / (t1 - t0) * P0 + (t - t0) / (t1 - t0) * P1 A2 = (t2 - t) / (t2 - t1) * P1 + (t - t1) / (t2 - t1) * P2 A3 = (t3 - t) / (t3 - t2) * P2 + (t - t2) / (t3 - t2) * P3 B1 = (t2 - t) / (t2 - t0) * A1 + (t - t0) / (t2 - t0) * A2 B2 = (t3 - t) / (t3 - t1) * A2 + (t - t1) / (t3 - t1) * A3 points = (t2 - t) / (t2 - t1) * B1 + (t - t1) / (t2 - t1) * B2 return points def catmull_rom_chain(points: tuple, num_points: int) -> list:  """  Calculate Catmull-Rom for a sequence of initial points and return the combined curve.  :param points: Base points from which the quadruples for the algorithm are taken  :param num_points: The number of points to include in each curve segment  :return: The chain of all points (points of all segments)  """ point_quadruples = ( # Prepare function inputs (points[idx_segment_start + d] for d in range(QUADRUPLE_SIZE)) for idx_segment_start in range(num_segments(points)) ) all_splines = (catmull_rom_spline(*pq, num_points) for pq in point_quadruples) return flatten(all_splines) if __name__ == "__main__": POINTS: tuple = ((0, 1.5), (2, 2), (3, 1), (4, 0.5), (5, 1), (6, 2), (7, 3)) # Red points NUM_POINTS: int = 100 # Density of blue chain points between two red points chain_points: list = catmull_rom_chain(POINTS, NUM_POINTS) assert len(chain_points) == num_segments(POINTS) * NUM_POINTS # 400 blue points for this example plt.plot(*zip(*chain_points), c="blue") plt.plot(*zip(*POINTS), c="red", linestyle="none", marker="o") plt.show() 
 
Plot obtained by the Python example code given above

Code example in Unity C# edit

using UnityEngine; // a single catmull-rom curve public struct CatmullRomCurve {  public Vector2 p0, p1, p2, p3;  public float alpha;  public CatmullRomCurve(Vector2 p0, Vector2 p1, Vector2 p2, Vector2 p3, float alpha)  {  (this.p0, this.p1, this.p2, this.p3) = (p0, p1, p2, p3);  this.alpha = alpha;  }  // Evaluates a point at the given t-value from 0 to 1  public Vector2 GetPoint(float t)  {  // calculate knots  const float k0 = 0;  float k1 = GetKnotInterval(p0, p1);  float k2 = GetKnotInterval(p1, p2) + k1;  float k3 = GetKnotInterval(p2, p3) + k2;  // evaluate the point  float u = Mathf.LerpUnclamped(k1, k2, t);  Vector2 A1 = Remap(k0, k1, p0, p1, u);  Vector2 A2 = Remap(k1, k2, p1, p2, u);  Vector2 A3 = Remap(k2, k3, p2, p3, u);  Vector2 B1 = Remap(k0, k2, A1, A2, u);  Vector2 B2 = Remap(k1, k3, A2, A3, u);  return Remap(k1, k2, B1, B2, u);  }  static Vector2 Remap(float a, float b, Vector2 c, Vector2 d, float u)  {  return Vector2.LerpUnclamped(c, d, (u - a) / (b - a));  }  float GetKnotInterval(Vector2 a, Vector2 b)  {  return Mathf.Pow(Vector2.SqrMagnitude(a - b), 0.5f * alpha);  } } 


using UnityEngine; // Draws a catmull-rom spline in the scene view, // along the child objects of the transform of this component public class CatmullRomSpline : MonoBehaviour {  [Range(0, 1)]  public float alpha = 0.5f;  int PointCount => transform.childCount;  int SegmentCount => PointCount - 3;  Vector2 GetPoint(int i) => transform.GetChild(i).position;  CatmullRomCurve GetCurve(int i)  {  return new CatmullRomCurve(GetPoint(i), GetPoint(i+1), GetPoint(i+2), GetPoint(i+3), alpha);  }  void OnDrawGizmos()  {  for (int i = 0; i < SegmentCount; i++)  DrawCurveSegment(GetCurve(i));  }  void DrawCurveSegment(CatmullRomCurve curve)  {  const int detail = 32;  Vector2 prev = curve.p1;  for (int i = 1; i < detail; i++)  {  float t = i / (detail - 1f);  Vector2 pt = curve.GetPoint(t);  Gizmos.DrawLine(prev, pt);  prev = pt;  }  } } 

Code example in Unreal C++ edit

float GetT( float t, float alpha, const FVector& p0, const FVector& p1 ) {  auto d = p1 - p0;  float a = d | d; // Dot product  float b = FMath::Pow( a, alpha*.5f );  return (b + t); } FVector CatmullRom( const FVector& p0, const FVector& p1, const FVector& p2, const FVector& p3, float t /* between 0 and 1 */, float alpha=.5f /* between 0 and 1 */ ) {  float t0 = 0.0f;  float t1 = GetT( t0, alpha, p0, p1 );  float t2 = GetT( t1, alpha, p1, p2 );  float t3 = GetT( t2, alpha, p2, p3 );  t = FMath::Lerp( t1, t2, t );  FVector A1 = ( t1-t )/( t1-t0 )*p0 + ( t-t0 )/( t1-t0 )*p1;  FVector A2 = ( t2-t )/( t2-t1 )*p1 + ( t-t1 )/( t2-t1 )*p2;  FVector A3 = ( t3-t )/( t3-t2 )*p2 + ( t-t2 )/( t3-t2 )*p3;  FVector B1 = ( t2-t )/( t2-t0 )*A1 + ( t-t0 )/( t2-t0 )*A2;  FVector B2 = ( t3-t )/( t3-t1 )*A2 + ( t-t1 )/( t3-t1 )*A3;  FVector C = ( t2-t )/( t2-t1 )*B1 + ( t-t1 )/( t2-t1 )*B2;  return C; } 

See also edit

References edit

  1. ^ Catmull, Edwin; Rom, Raphael (1974). "A class of local interpolating splines". In Barnhill, Robert E.; Riesenfeld, Richard F. (eds.). Computer Aided Geometric Design. pp. 317–326. doi:10.1016/B978-0-12-079050-0.50020-5. ISBN 978-0-12-079050-0.
  2. ^ Barry, Phillip J.; Goldman, Ronald N. (August 1988). A recursive evaluation algorithm for a class of Catmull–Rom splines. Proceedings of the 15st Annual Conference on Computer Graphics and Interactive Techniques, SIGGRAPH 1988. Vol. 22. Association for Computing Machinery. pp. 199–204. doi:10.1145/378456.378511.
  3. ^ Yuksel, Cem; Schaefer, Scott; Keyser, John (July 2011). "Parameterization and applications of Catmull-Rom curves". Computer-Aided Design. 43 (7): 747–755. CiteSeerX 10.1.1.359.9148. doi:10.1016/j.cad.2010.08.008.
  4. ^ Yuksel; Schaefer; Keyser, Cem; Scott; John. "On the Parameterization of Catmull-Rom Curves" (PDF).{{cite web}}: CS1 maint: multiple names: authors list (link)
  5. ^ Jen Hong, Tan; Acharya, U. Rajendra (2014). "Active spline model: A shape based model-interactive segmentation" (PDF). Digital Signal Processing. 35: 64–74. arXiv:1402.6387. doi:10.1016/j.dsp.2014.09.002. S2CID 6953844.

External links edit

  • Catmull-Rom curve with no cusps and no self-intersections – implementation in Java
  • Catmull-Rom curve with no cusps and no self-intersections – simplified implementation in C++
  • Catmull-Rom splines – interactive generation via Python, in a Jupyter notebook
  • Smooth Paths Using Catmull-Rom Splines – another versatile implementation in C++ including centripetal CR splines

centripetal, catmull, spline, computer, graphics, centripetal, catmull, spline, variant, form, catmull, spline, originally, formulated, edwin, catmull, raphael, which, evaluated, using, recursive, algorithm, proposed, barry, goldman, type, interpolating, splin. In computer graphics the centripetal Catmull Rom spline is a variant form of the Catmull Rom spline originally formulated by Edwin Catmull and Raphael Rom 1 which can be evaluated using a recursive algorithm proposed by Barry and Goldman 2 It is a type of interpolating spline a curve that goes through its control points defined by four control points P0 P1 P2 P3 displaystyle mathbf P 0 mathbf P 1 mathbf P 2 mathbf P 3 with the curve drawn only from P1 displaystyle mathbf P 1 to P2 displaystyle mathbf P 2 Catmull Rom spline interpolation with four pointsContents 1 Definition 2 Advantages 3 Other uses 4 Code example in Python 5 Code example in Unity C 6 Code example in Unreal C 7 See also 8 References 9 External linksDefinition edit nbsp Barry and Goldman s pyramidal formulation nbsp Knot parameterization for the Catmull Rom algorithmLet Pi xiyi T displaystyle mathbf P i x i quad y i T nbsp denote a point For a curve segment C displaystyle mathbf C nbsp defined by points P0 P1 P2 P3 displaystyle mathbf P 0 mathbf P 1 mathbf P 2 mathbf P 3 nbsp and knot sequence t0 t1 t2 t3 displaystyle t 0 t 1 t 2 t 3 nbsp the centripetal Catmull Rom spline can be produced by C t2 tt2 t1B1 t t1t2 t1B2 displaystyle mathbf C frac t 2 t t 2 t 1 mathbf B 1 frac t t 1 t 2 t 1 mathbf B 2 nbsp where B1 t2 tt2 t0A1 t t0t2 t0A2 displaystyle mathbf B 1 frac t 2 t t 2 t 0 mathbf A 1 frac t t 0 t 2 t 0 mathbf A 2 nbsp B2 t3 tt3 t1A2 t t1t3 t1A3 displaystyle mathbf B 2 frac t 3 t t 3 t 1 mathbf A 2 frac t t 1 t 3 t 1 mathbf A 3 nbsp A1 t1 tt1 t0P0 t t0t1 t0P1 displaystyle mathbf A 1 frac t 1 t t 1 t 0 mathbf P 0 frac t t 0 t 1 t 0 mathbf P 1 nbsp A2 t2 tt2 t1P1 t t1t2 t1P2 displaystyle mathbf A 2 frac t 2 t t 2 t 1 mathbf P 1 frac t t 1 t 2 t 1 mathbf P 2 nbsp A3 t3 tt3 t2P2 t t2t3 t2P3 displaystyle mathbf A 3 frac t 3 t t 3 t 2 mathbf P 2 frac t t 2 t 3 t 2 mathbf P 3 nbsp and ti 1 xi 1 xi 2 yi 1 yi 2 a ti displaystyle t i 1 left sqrt x i 1 x i 2 y i 1 y i 2 right alpha t i nbsp in which a displaystyle alpha nbsp ranges from 0 to 1 for knot parameterization and i 0 1 2 3 displaystyle i 0 1 2 3 nbsp with t0 0 displaystyle t 0 0 nbsp For centripetal Catmull Rom spline the value of a displaystyle alpha nbsp is 0 5 displaystyle 0 5 nbsp When a 0 displaystyle alpha 0 nbsp the resulting curve is the standard uniform Catmull Rom spline when a 1 displaystyle alpha 1 nbsp the result is a chordal Catmull Rom spline nbsp Gif animation for uniform centripetal and chordal parameterization of Catmull Rom spline depending on the a valuePlugging t t1 displaystyle t t 1 nbsp into the spline equations A1 A2 A3 B1 B2 displaystyle mathbf A 1 mathbf A 2 mathbf A 3 mathbf B 1 mathbf B 2 nbsp and C displaystyle mathbf C nbsp shows that the value of the spline curve at t1 displaystyle t 1 nbsp is C P1 displaystyle mathbf C mathbf P 1 nbsp Similarly substituting t t2 displaystyle t t 2 nbsp into the spline equations shows that C P2 displaystyle mathbf C mathbf P 2 nbsp at t2 displaystyle t 2 nbsp This is true independent of the value of a displaystyle alpha nbsp since the equation for ti 1 displaystyle t i 1 nbsp is not needed to calculate the value of C displaystyle mathbf C nbsp at points t1 displaystyle t 1 nbsp and t2 displaystyle t 2 nbsp nbsp 3D centripetal Catmull Rom spline segment The extension to 3D points is simply achieved by considering Pi xiyizi T displaystyle mathbf P i x i quad y i quad z i T nbsp a generic 3D point Pi displaystyle mathbf P i nbsp and ti 1 xi 1 xi 2 yi 1 yi 2 zi 1 zi 2 a ti displaystyle t i 1 left sqrt x i 1 x i 2 y i 1 y i 2 z i 1 z i 2 right alpha t i nbsp Advantages editCentripetal Catmull Rom spline has several desirable mathematical properties compared to the original and the other types of Catmull Rom formulation 3 First it will not form loop or self intersection within a curve segment Second cusp will never occur within a curve segment Third it follows the control points more tightly 4 vague nbsp In this figure there is a self intersection loop on the uniform Catmull Rom spline green whereas for chordal Catmull Rom spline red the curve does not follow tightly through the control points Other uses editIn computer vision centripetal Catmull Rom spline has been used to formulate an active model for segmentation The method is termed active spline model 5 The model is devised on the basis of active shape model but uses centripetal Catmull Rom spline to join two successive points active shape model uses simple straight line so that the total number of points necessary to depict a shape is less The use of centripetal Catmull Rom spline makes the training of a shape model much simpler and it enables a better way to edit a contour after segmentation Code example in Python editThe following is an implementation of the Catmull Rom spline in Python that produces the plot shown beneath import numpy import matplotlib pyplot as plt QUADRUPLE SIZE int 4 def num segments point chain tuple gt int There is 1 segment per 4 points so we must subtract 3 from the number of points return len point chain QUADRUPLE SIZE 1 def flatten list of lists gt list E g mapping 1 2 3 4 5 to 1 2 3 4 5 return elem for lst in list of lists for elem in lst def catmull rom spline P0 tuple P1 tuple P2 tuple P3 tuple num points int alpha float 0 5 Compute the points in the spline segment param P0 P1 P2 and P3 The x y point pairs that define the Catmull Rom spline param num points The number of points to include in the resulting curve segment param alpha 0 5 for the centripetal spline 0 0 for the uniform spline 1 0 for the chordal spline return The points Calculate t0 to t4 Then only calculate points between P1 and P2 Reshape linspace so that we can multiply by the points P0 to P3 and get a point for each value of t def tj ti float pi tuple pj tuple gt float xi yi pi xj yj pj dx dy xj xi yj yi l dx 2 dy 2 0 5 return ti l alpha t0 float 0 0 t1 float tj t0 P0 P1 t2 float tj t1 P1 P2 t3 float tj t2 P2 P3 t numpy linspace t1 t2 num points reshape num points 1 A1 t1 t t1 t0 P0 t t0 t1 t0 P1 A2 t2 t t2 t1 P1 t t1 t2 t1 P2 A3 t3 t t3 t2 P2 t t2 t3 t2 P3 B1 t2 t t2 t0 A1 t t0 t2 t0 A2 B2 t3 t t3 t1 A2 t t1 t3 t1 A3 points t2 t t2 t1 B1 t t1 t2 t1 B2 return points def catmull rom chain points tuple num points int gt list Calculate Catmull Rom for a sequence of initial points and return the combined curve param points Base points from which the quadruples for the algorithm are taken param num points The number of points to include in each curve segment return The chain of all points points of all segments point quadruples Prepare function inputs points idx segment start d for d in range QUADRUPLE SIZE for idx segment start in range num segments points all splines catmull rom spline pq num points for pq in point quadruples return flatten all splines if name main POINTS tuple 0 1 5 2 2 3 1 4 0 5 5 1 6 2 7 3 Red points NUM POINTS int 100 Density of blue chain points between two red points chain points list catmull rom chain POINTS NUM POINTS assert len chain points num segments POINTS NUM POINTS 400 blue points for this example plt plot zip chain points c blue plt plot zip POINTS c red linestyle none marker o plt show nbsp Plot obtained by the Python example code given aboveCode example in Unity C editusing UnityEngine a single catmull rom curve public struct CatmullRomCurve public Vector2 p0 p1 p2 p3 public float alpha public CatmullRomCurve Vector2 p0 Vector2 p1 Vector2 p2 Vector2 p3 float alpha this p0 this p1 this p2 this p3 p0 p1 p2 p3 this alpha alpha Evaluates a point at the given t value from 0 to 1 public Vector2 GetPoint float t calculate knots const float k0 0 float k1 GetKnotInterval p0 p1 float k2 GetKnotInterval p1 p2 k1 float k3 GetKnotInterval p2 p3 k2 evaluate the point float u Mathf LerpUnclamped k1 k2 t Vector2 A1 Remap k0 k1 p0 p1 u Vector2 A2 Remap k1 k2 p1 p2 u Vector2 A3 Remap k2 k3 p2 p3 u Vector2 B1 Remap k0 k2 A1 A2 u Vector2 B2 Remap k1 k3 A2 A3 u return Remap k1 k2 B1 B2 u static Vector2 Remap float a float b Vector2 c Vector2 d float u return Vector2 LerpUnclamped c d u a b a float GetKnotInterval Vector2 a Vector2 b return Mathf Pow Vector2 SqrMagnitude a b 0 5f alpha using UnityEngine Draws a catmull rom spline in the scene view along the child objects of the transform of this component public class CatmullRomSpline MonoBehaviour Range 0 1 public float alpha 0 5f int PointCount gt transform childCount int SegmentCount gt PointCount 3 Vector2 GetPoint int i gt transform GetChild i position CatmullRomCurve GetCurve int i return new CatmullRomCurve GetPoint i GetPoint i 1 GetPoint i 2 GetPoint i 3 alpha void OnDrawGizmos for int i 0 i lt SegmentCount i DrawCurveSegment GetCurve i void DrawCurveSegment CatmullRomCurve curve const int detail 32 Vector2 prev curve p1 for int i 1 i lt detail i float t i detail 1f Vector2 pt curve GetPoint t Gizmos DrawLine prev pt prev pt Code example in Unreal C editfloat GetT float t float alpha const FVector amp p0 const FVector amp p1 auto d p1 p0 float a d d Dot product float b FMath Pow a alpha 5f return b t FVector CatmullRom const FVector amp p0 const FVector amp p1 const FVector amp p2 const FVector amp p3 float t between 0 and 1 float alpha 5f between 0 and 1 float t0 0 0f float t1 GetT t0 alpha p0 p1 float t2 GetT t1 alpha p1 p2 float t3 GetT t2 alpha p2 p3 t FMath Lerp t1 t2 t FVector A1 t1 t t1 t0 p0 t t0 t1 t0 p1 FVector A2 t2 t t2 t1 p1 t t1 t2 t1 p2 FVector A3 t3 t t3 t2 p2 t t2 t3 t2 p3 FVector B1 t2 t t2 t0 A1 t t0 t2 t0 A2 FVector B2 t3 t t3 t1 A2 t t1 t3 t1 A3 FVector C t2 t t2 t1 B1 t t1 t2 t1 B2 return C See also editCubic Hermite splinesReferences edit Catmull Edwin Rom Raphael 1974 A class of local interpolating splines In Barnhill Robert E Riesenfeld Richard F eds Computer Aided Geometric Design pp 317 326 doi 10 1016 B978 0 12 079050 0 50020 5 ISBN 978 0 12 079050 0 Barry Phillip J Goldman Ronald N August 1988 A recursive evaluation algorithm for a class of Catmull Rom splines Proceedings of the 15st Annual Conference on Computer Graphics and Interactive Techniques SIGGRAPH 1988 Vol 22 Association for Computing Machinery pp 199 204 doi 10 1145 378456 378511 Yuksel Cem Schaefer Scott Keyser John July 2011 Parameterization and applications of Catmull Rom curves Computer Aided Design 43 7 747 755 CiteSeerX 10 1 1 359 9148 doi 10 1016 j cad 2010 08 008 Yuksel Schaefer Keyser Cem Scott John On the Parameterization of Catmull Rom Curves PDF a href Template Cite web html title Template Cite web cite web a CS1 maint multiple names authors list link Jen Hong Tan Acharya U Rajendra 2014 Active spline model A shape based model interactive segmentation PDF Digital Signal Processing 35 64 74 arXiv 1402 6387 doi 10 1016 j dsp 2014 09 002 S2CID 6953844 External links editCatmull Rom curve with no cusps and no self intersections implementation in Java Catmull Rom curve with no cusps and no self intersections simplified implementation in C Catmull Rom splines interactive generation via Python in a Jupyter notebook Smooth Paths Using Catmull Rom Splines another versatile implementation in C including centripetal CR splines Retrieved from https en wikipedia org w index php title Centripetal Catmull Rom spline amp oldid 1178082051, wikipedia, wiki, book, books, library,

article

, read, download, free, free download, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, picture, music, song, movie, book, game, games.