<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: compilelife</title>
    <description>The latest articles on DEV Community by compilelife (@compilelife).</description>
    <link>https://dev.to/compilelife</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1847705%2F9a6f766b-bbce-4dd7-a1cf-146f3c29c6a6.jpeg</url>
      <title>DEV Community: compilelife</title>
      <link>https://dev.to/compilelife</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/compilelife"/>
    <language>en</language>
    <item>
      <title>Simply understanding Bézier curves.</title>
      <dc:creator>compilelife</dc:creator>
      <pubDate>Fri, 16 Aug 2024 00:55:39 +0000</pubDate>
      <link>https://dev.to/compilelife/simply-understanding-bezier-curves-39kh</link>
      <guid>https://dev.to/compilelife/simply-understanding-bezier-curves-39kh</guid>
      <description>&lt;p&gt;Imagine if you could only use straight lines, ellipses, and circles, wouldn't it be difficult to design a car with smooth lines and a complex appearance?&lt;/p&gt;

&lt;p&gt;In 1962, the French engineer Pierre Bézier published the Bézier curve, which was initially used for the main body design of cars.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiamqo4nk2ikbheesmc5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiamqo4nk2ikbheesmc5a.png" alt="bezier preview" width="503" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bézier curves can define a smooth curve through a series of control points. The curve always passes through the first and last control points and is influenced by the shape of the intermediate control points. Additionally, Bézier curves have the property of convex hulls.&lt;/p&gt;

&lt;p&gt;Bézier curves are widely used in computer graphics and image modeling, such as in animation, font design, and industrial design.&lt;/p&gt;

&lt;h2&gt;
  
  
  Formula
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmydhilr7f7yqdee1agb3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmydhilr7f7yqdee1agb3.png" alt="formula" width="235" height="81"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's understand this.&lt;/p&gt;

&lt;p&gt;P(t) represents a point on the curve at t (t is a fraction, with a value from 0 to 1). What is a point on the curve at t? A common curve description is: y = f(x), and for now, let's understand P(t) as f(x). The difference is that P(t) is a parametric representation (and the calculation result is a "vector" like [x, y]), which will be explained in detail later.&lt;/p&gt;

&lt;p&gt;Next, Pi represents the i-th control point (i starts from 0). Taking the above figure as an example, there are 4 control points, which are P0, P1, P2, P3. The n in the formula is the last index of the control points, that is, n = 3 (note that it is not the number of control points, but the count minus 1).&lt;/p&gt;

&lt;p&gt;Bi,n(t) is the Bernstein basis function, also known as the basis function. For each specific (i, n), there is a different basis function corresponding to it. If you understand from a weighted perspective, you can consider the basis function as a weight function, indicating the "contribution" of the i-th control point Pi to the curve coordinates at the position of t.&lt;/p&gt;

&lt;p&gt;The formula for the basis function is as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyuynxfjhujbqi57k65l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwyuynxfjhujbqi57k65l.png" alt="basis function" width="241" height="60"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;

&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;(ni)\binom{n}{i} &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mopen delimcenter"&gt;&lt;span class="delimsizing size1"&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span class="mfrac"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mclose delimcenter"&gt;&lt;span class="delimsizing size1"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 Is the combination number (how many ways to choose i out of n?). As for why the basis function looks like this, it can be understood in connection with the De Casteljau algorithm (see later in the text)&lt;/p&gt;

&lt;p&gt;Back to the P(t) formula, 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;∑i=0n\sum_{i=0}^{n} &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mop"&gt;&lt;span class="mop op-symbol small-op"&gt;∑&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mrel mtight"&gt;=&lt;/span&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 is the summation symbol, indicating that the subsequent part ( 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;Bi,n(t)⋅PiB_{i,n}(t) \cdot P_i&lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;B&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;span class="mpunct mtight"&gt;,&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="mopen"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal"&gt;t&lt;/span&gt;&lt;span class="mclose"&gt;)&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;span class="mbin"&gt;⋅&lt;/span&gt;&lt;span class="mspace"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;P&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mathnormal mtight"&gt;i&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
) is to be summed from i=0 to i=n.&lt;/p&gt;

&lt;p&gt;Taking the above figure as an example, assuming we want to calculate P(0.1), how to do it? It is expanded as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyo7wxyjet6agopxc5gvm.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyo7wxyjet6agopxc5gvm.png" alt="cal P(0.1)" width="624" height="101"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq32etl1jinwu7q13fdsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq32etl1jinwu7q13fdsi.png" alt="cal P(0.1)" width="554" height="53"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Substitute t=0.1 to get:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdfkyv3pzk77uxh7a043.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvdfkyv3pzk77uxh7a043.png" alt="cal P(0.1)" width="499" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Parametric representation of the curve
&lt;/h2&gt;

&lt;p&gt;Here directly cites an article from a netizen (&lt;a href="https://mp.weixin.qq.com/s?__biz=MzI1NTM1NTcxMw==&amp;amp;mid=2247491646&amp;amp;idx=1&amp;amp;sn=5ef9931ae6cf046276dba7ddad9016eb&amp;amp;chksm=ea359e10dd42170619a543ec510641d12f86862858133fbd0f780bd6c5e585cc5bab4e3d77d2&amp;amp;scene=27" rel="noopener noreferrer"&gt;link&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm51itgp7vhx66dzo63hn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fm51itgp7vhx66dzo63hn.png" alt="line" width="617" height="658"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's focus on the formula above. &lt;/p&gt;

&lt;p&gt;As shown in the figure above, the straight line we are familiar with can be understood from another perspective: using t (i.e., the length of |AP| from the point P to the known point (x0,y0)), then point P can be determined through the above trigonometric functions.&lt;/p&gt;

&lt;p&gt;More generally, it can be written as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz35uconv44c9823ibs51.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz35uconv44c9823ibs51.png" alt="line Parametric " width="183" height="70"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here, P0 is the vector [x0,y0]and v is also a vector. When added together, P(t)is the vector [x,y].&lt;/p&gt;

&lt;p&gt;Looking at the circle again:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngrr0bi7u18ol55wnaxw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fngrr0bi7u18ol55wnaxw.png" alt="circle" width="720" height="609"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As shown in the diagram, the circle can be viewed as having a known center, with any point on the circle being determined by the rotation angle and the radius. It can also be written as:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm9764n8712oj1ypusfb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm9764n8712oj1ypusfb.png" alt="circle Parametric" width="184" height="65"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The parametric equations maintain geometric invariance and can represent shapes like circles (where one x corresponds to multiple y values).&lt;/p&gt;

&lt;h2&gt;
  
  
  De Casteljau
&lt;/h2&gt;

&lt;p&gt;The De Casteljau algorithm is a method used in practical applications to evaluate and approximate Bézier curves for drawing and other operations. Compared to the previous definition-based evaluation method, it is faster and more stable, and closer to the characteristics of Bézier curves.&lt;/p&gt;

&lt;p&gt;Here, we refer to two articles: &lt;a href="https://en.wikipedia.org/wiki/De_Casteljau%27s_algorithm" rel="noopener noreferrer"&gt;link1&lt;/a&gt; and &lt;a href="https://liolok.com/zhs/bezier-curve-and-de-casteljau-algorithm/" rel="noopener noreferrer"&gt;link2&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Firstly, the following is defined:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqjrz3hx7frxgwpe2mew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdqjrz3hx7frxgwpe2mew.png" alt="De Casteljau" width="800" height="490"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Look at the above β. It's a bit confusing with the superscripts and subscripts; you can use the following triangular recursion for understanding:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frc5ttlns6bolrr47o0hr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frc5ttlns6bolrr47o0hr.png" alt="iteration" width="469" height="498"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The red edges of the triangle in the above figure are the control points of the two segments divided by t0. To more vividly understand t0, P(t0) （i.e., 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;β0(n)\beta_0^{(n)} &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;β&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
 ）, the control points of the two curves, you can refer to the following figure:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpge205nvm70fnfg7wasa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpge205nvm70fnfg7wasa.png" alt="detail iteration" width="388" height="332"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The figure above demonstrates the relationships between various points when t=0.5.&lt;/p&gt;

&lt;p&gt;From the perspective of "interpolation," the calculation process can also be understood as: &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Finding the midpoints of each pair of adjacent control points (because t=0.5), that is, b01, b11, b21  (please forgive my notation; writing in LaTeX is too troublesome)&lt;/li&gt;
&lt;li&gt;Find the midpoint b02 on b01−b11, and find the midpoint b12 on b11-b21&lt;/li&gt;
&lt;li&gt;Find the midpoint b03 on b02−b12
​
In fact, the essence of the De Casteljau algorithm is interpolation and iteration.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Curve Drawing Based on De Casteljau
&lt;/h2&gt;

&lt;p&gt;Currently, two methods are observed.&lt;/p&gt;

&lt;p&gt;One method involves traversing t from 0 to 1 with small step increments（i.e. 0.01). Each time P(t) is sought, a recursive formula is used to determine 
&lt;span class="katex-element"&gt;
  &lt;span class="katex"&gt;&lt;span class="katex-mathml"&gt;β0(n)\beta_0^{(n)} &lt;/span&gt;&lt;span class="katex-html"&gt;&lt;span class="base"&gt;&lt;span class="strut"&gt;&lt;/span&gt;&lt;span class="mord"&gt;&lt;span class="mord mathnormal"&gt;β&lt;/span&gt;&lt;span class="msupsub"&gt;&lt;span class="vlist-t vlist-t2"&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;0&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span&gt;&lt;span class="pstrut"&gt;&lt;/span&gt;&lt;span class="sizing reset-size6 size3 mtight"&gt;&lt;span class="mord mtight"&gt;&lt;span class="mopen mtight"&gt;(&lt;/span&gt;&lt;span class="mord mathnormal mtight"&gt;n&lt;/span&gt;&lt;span class="mclose mtight"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-s"&gt;​&lt;/span&gt;&lt;/span&gt;&lt;span class="vlist-r"&gt;&lt;span class="vlist"&gt;&lt;span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/span&gt;
.&lt;/p&gt;

&lt;p&gt;The other method involves seeking P(t=0.5), and then for the two divided curves, P(t=0.5) is sought respectively... This subdivision continues until the curve is approximated.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implementation
&lt;/h2&gt;

&lt;p&gt;It always feels unreal to just watch without practicing.&lt;/p&gt;

&lt;p&gt;So I wrote my own implementation code for curve drawing and organized it into a toolkit: &lt;a href="https://compilelife.github.io/#/bezier" rel="noopener noreferrer"&gt;Compilelife's Toolkit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Corresponding core code is &lt;a href="https://github.com/compilelife/compilelife.github.io/blob/fbbcfa51d48097fbc61f33c35e2ab7aa543417ef/src/tools/bezier.js#L292" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

</description>
      <category>bezier</category>
      <category>computergraphics</category>
      <category>javascript</category>
      <category>learning</category>
    </item>
    <item>
      <title>Painful Analyse Log ? Your Approach Might Be Wrong</title>
      <dc:creator>compilelife</dc:creator>
      <pubDate>Sun, 28 Jul 2024 08:45:33 +0000</pubDate>
      <link>https://dev.to/compilelife/painful-analyse-log-your-approach-might-be-wrong-58b0</link>
      <guid>https://dev.to/compilelife/painful-analyse-log-your-approach-might-be-wrong-58b0</guid>
      <description>&lt;p&gt;You've likely identified numerous bugs from various error logs, but have also been troubled countless times by lengthy and complex logs.&lt;/p&gt;

&lt;p&gt;I also often suffer from the agony of log reviewing, typically due to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Log files are so large that it's difficult to even open them.&lt;/li&gt;
&lt;li&gt;The information within the log files is intricately intertwined, with the sequences of various modules being unclear.&lt;/li&gt;
&lt;li&gt;The log are split into multiple parts, necessitating constant switching between them&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Not only are the logs hard to stomach, but the tools for viewing them are also not user-friendly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;After searching for a keyword and jumping around a bit, I often forget what I was doing (Who am I, where am I, what am I doing?).&lt;/li&gt;
&lt;li&gt;When I want to filter logs by a certain keyword, some tools don't even support it.&lt;/li&gt;
&lt;li&gt;Just when I've got my analysis all figured out, I forget how to start explaining it as soon as someone else comes over.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These issues can be divided into two categories: first, the tools themselves are problematic, with insufficient functionality; second, there is a lack of systematic methods for troubleshooting issues from logs.&lt;/p&gt;

&lt;p&gt;For the former, what we need are professional log viewing tools, not just editors; for the latter, I have summarized some methodologies that I can share.&lt;/p&gt;

&lt;h2&gt;
  
  
  Visualization of Thought Process
&lt;/h2&gt;

&lt;p&gt;The general steps for troubleshooting logs are: Understand the problem =&amp;gt; Locate the error =&amp;gt; Examine the context =&amp;gt; Infer the cause of the error.&lt;/p&gt;

&lt;p&gt;In this process, if you consider the logs as a one-dimensional line, then reviewing the logs is like jumping back and forth along the line, gathering information, and drawing conclusions.&lt;/p&gt;

&lt;p&gt;The problems mentioned above, such as forgetting where you've read in the logs, or not knowing where to start when explaining to others, are due to not recording your browsing path, gathered information, summarized doubts, and tentative hypotheses in real-time.&lt;/p&gt;

&lt;p&gt;What is the most suitable way to record and visualize these elements? I believe it is the "Timeline."&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdzz8n0baecb6q6frm2e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdzz8n0baecb6q6frm2e.png" alt="timeline" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How do we use a &lt;strong&gt;timeline&lt;/strong&gt;? Imagine you are organizing historical events. When you find something valuable in the logs (a significant event), you place that spot (log line) into the timeline, becoming a "node."&lt;/p&gt;

&lt;p&gt;At first, the timeline is just a bookmark bar, helping us record location information. For example, where the error occurred, what was happening at a certain time, what happened before or after something else, etc.&lt;/p&gt;

&lt;p&gt;Next, we start to combine the logs with the timeline, gradually discovering some doubts. If a place seems suspicious, we add a comment to that node; if a value printed seems wrong, we color that node yellow... This is very similar to a mind map.&lt;/p&gt;

&lt;p&gt;The process above, which seems to be centered around organizing log events along the "timeline," is essentially an examination of our own thought process (identifying suspicious points, connecting before and after, and arguing). In other words, at this point, the "timeline" is already playing the role of visualizing our thought process.&lt;/p&gt;

&lt;p&gt;Using visualization brings another benefit: we can send this organized timeline to workmate to explain our log analysis process. Isn't this more intuitive than just using plain text descriptions?&lt;/p&gt;

&lt;h2&gt;
  
  
  Primary + Auxiliary
&lt;/h2&gt;

&lt;p&gt;The "timeline" mentioned above serves as a consistent place to record, edit, and visualize thoughts without being disturbed or interrupted by other information.&lt;/p&gt;

&lt;p&gt;While the timeline helps us maintain our thought process along the dimension of time, the "filter window" helps us keep our thought process on track along the dimension of information.&lt;/p&gt;

&lt;p&gt;In log troubleshooting, it's common to filter logs containing a specific keyword to focus on a particular topic (information filtering). But is filtering enough?&lt;/p&gt;

&lt;p&gt;Filtering can lead to the loss of information. What we need to understand is what's happening in the entire log with the filtered log entries, where they are distributed, what the context (other modules) is doing, and how they relate to the nodes (events) in the timeline before and after...&lt;/p&gt;

&lt;p&gt;In other words, the auxiliary information filtered by keywords, in addition to its own informational value, also needs to be extracted against the main log to obtain more information. In other words, it is both parallel and intertwined.&lt;/p&gt;

&lt;p&gt;So, How to reasonably resolve this contradiction?&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrr7jsamnxd2slqaof31.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmrr7jsamnxd2slqaof31.png" alt="Primary + Auxiliary" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are three major areas in the image above: the &lt;strong&gt;main window&lt;/strong&gt; in the upper left, the &lt;strong&gt;filter pane&lt;/strong&gt; in the lower left, and the &lt;strong&gt;timeline&lt;/strong&gt; on the right.&lt;/p&gt;

&lt;p&gt;I define the information filtered by keywords as auxiliary information, placed in the filter pane, and the main window displays the complete log to achieve parallel viewing.&lt;/p&gt;

&lt;p&gt;At the same time, using 'time' as the 'link' to connect the 'main window', 'filter pane', and 'timeline', no matter which event is clicked in any of the windows, the other two windows will immediately locate to the corresponding position, thus achieving the interweaving of information.&lt;/p&gt;

&lt;h2&gt;
  
  
  TAG
&lt;/h2&gt;

&lt;p&gt;Viewing logs is not something that can be accomplished by just searching for one or two keywords (what can be done by searching for one or two keywords is merely a cursory glance), but it involves many. Therefore, it would be best to record the searched keywords, and ideally, mark them with different colors.&lt;/p&gt;

&lt;p&gt;So, I also designed a TAG bar to record the currently highlighted keywords.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuggc9kofsie9rs9m7zl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwuggc9kofsie9rs9m7zl.png" alt="TAG" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Segmented log
&lt;/h2&gt;

&lt;p&gt;Of course, we won't forget about segmented logs. The most direct and intuitive way to deal with them is to 'reassemble' them! By viewing them in memory in a 'continuous' manner, we can forget that they are segmented during analysis and operate seamlessly as if analyzing a single 'large log'.&lt;/p&gt;

&lt;p&gt;Of course, different log segmentation rules will produce different segmentation reassembly rules. This point must not be overlooked in tool support.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4xy3c5i4hzygp6kxhn5c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4xy3c5i4hzygp6kxhn5c.png" alt="Segmented log" width="800" height="524"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  More
&lt;/h2&gt;

&lt;p&gt;In order to reviewing logs "happily", functions such as locating to a specific line, go forward/backward, reverse search, font settings... and so on, cannot be lacking.&lt;/p&gt;

&lt;p&gt;Since we have already explored certain experiences and methods in log analysis, and existing tools are not particularly convenient, of course I need to write one myself!&lt;/p&gt;

&lt;p&gt;Please have a look at the log analysis tool I've created: "Loginsight" (Available on mac apple store). &lt;/p&gt;

</description>
      <category>log</category>
      <category>productivity</category>
      <category>tooling</category>
    </item>
  </channel>
</rss>
