{"id":1649,"date":"2022-11-04T01:43:48","date_gmt":"2022-11-04T08:43:48","guid":{"rendered":"https:\/\/gantovnik.com\/bio-tips\/?p=1649"},"modified":"2022-11-04T01:43:48","modified_gmt":"2022-11-04T08:43:48","slug":"210-parametric-curve-in-3d-2-2-2-2-2-2-2-2-2-2-2-2-2-3-3-2-2-3-2-2-4-2-2-2-2","status":"publish","type":"post","link":"https:\/\/gantovnik.com\/bio-tips\/2022\/11\/210-parametric-curve-in-3d-2-2-2-2-2-2-2-2-2-2-2-2-2-3-3-2-2-3-2-2-4-2-2-2-2\/","title":{"rendered":"#313 Spline plot using C# Windows Forms App"},"content":{"rendered":"<p>Add ScottPlot.WinForms using Manage NuGet packages.<\/p>\n<p>Form1.cs<\/p>\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\nusing System.Data;\r\nusing System.Drawing;\r\nusing System.Linq;\r\nusing System.Text;\r\nusing System.Threading.Tasks;\r\nusing System.Windows.Forms;\r\nusing ScottPlot;\r\n\r\nnamespace Spline\r\n{\r\n    public partial class Form1 : Form\r\n    {\r\n        public static class Cubic\r\n        {\r\n            \/\/\/ &lt;summary&gt;\r\n            \/\/\/ Generate a smooth (interpolated) curve that follows the path of the given X\/Y points\r\n            \/\/\/ &lt;\/summary&gt;\r\n            public static (double&#x5B;] xs, double&#x5B;] ys) InterpolateXY(double&#x5B;] xs, double&#x5B;] ys, int count)\r\n            {\r\n                if (xs is null || ys is null || xs.Length != ys.Length)\r\n                    throw new ArgumentException($&quot;{nameof(xs)} and {nameof(ys)} must have same length&quot;);\r\n\r\n                int inputPointCount = xs.Length;\r\n                double&#x5B;] inputDistances = new double&#x5B;inputPointCount];\r\n                for (int i = 1; i &lt; inputPointCount; i++)\r\n                {\r\n                    double dx = xs&#x5B;i] - xs&#x5B;i - 1];\r\n                    double dy = ys&#x5B;i] - ys&#x5B;i - 1];\r\n                    double distance = Math.Sqrt(dx * dx + dy * dy);\r\n                    inputDistances&#x5B;i] = inputDistances&#x5B;i - 1] + distance;\r\n                }\r\n\r\n                double meanDistance = inputDistances.Last() \/ (count - 1);\r\n                double&#x5B;] evenDistances = Enumerable.Range(0, count).Select(x =&gt; x * meanDistance).ToArray();\r\n                double&#x5B;] xsOut = Interpolate(inputDistances, xs, evenDistances);\r\n                double&#x5B;] ysOut = Interpolate(inputDistances, ys, evenDistances);\r\n                return (xsOut, ysOut);\r\n            }\r\n\r\n            private static double&#x5B;] Interpolate(double&#x5B;] xOrig, double&#x5B;] yOrig, double&#x5B;] xInterp)\r\n            {\r\n                (double&#x5B;] a, double&#x5B;] b) = FitMatrix(xOrig, yOrig);\r\n\r\n                double&#x5B;] yInterp = new double&#x5B;xInterp.Length];\r\n                for (int i = 0; i &lt; yInterp.Length; i++)\r\n                {\r\n                    int j;\r\n                    for (j = 0; j &lt; xOrig.Length - 2; j++)\r\n                        if (xInterp&#x5B;i] &lt;= xOrig&#x5B;j + 1])\r\n                            break;\r\n\r\n                    double dx = xOrig&#x5B;j + 1] - xOrig&#x5B;j];\r\n                    double t = (xInterp&#x5B;i] - xOrig&#x5B;j]) \/ dx;\r\n                    double y = (1 - t) * yOrig&#x5B;j] + t * yOrig&#x5B;j + 1] +\r\n                        t * (1 - t) * (a&#x5B;j] * (1 - t) + b&#x5B;j] * t);\r\n                    yInterp&#x5B;i] = y;\r\n                }\r\n                return yInterp;\r\n            }\r\n            private static (double&#x5B;] a, double&#x5B;] b) FitMatrix(double&#x5B;] x, double&#x5B;] y)\r\n            {\r\n                int n = x.Length;\r\n                double&#x5B;] a = new double&#x5B;n - 1];\r\n                double&#x5B;] b = new double&#x5B;n - 1];\r\n                double&#x5B;] r = new double&#x5B;n];\r\n                double&#x5B;] A = new double&#x5B;n];\r\n                double&#x5B;] B = new double&#x5B;n];\r\n                double&#x5B;] C = new double&#x5B;n];\r\n\r\n                double dx1, dx2, dy1, dy2;\r\n\r\n                dx1 = x&#x5B;1] - x&#x5B;0];\r\n                C&#x5B;0] = 1.0f \/ dx1;\r\n                B&#x5B;0] = 2.0f * C&#x5B;0];\r\n                r&#x5B;0] = 3 * (y&#x5B;1] - y&#x5B;0]) \/ (dx1 * dx1);\r\n\r\n                for (int i = 1; i &lt; n - 1; i++)\r\n                {\r\n                    dx1 = x&#x5B;i] - x&#x5B;i - 1];\r\n                    dx2 = x&#x5B;i + 1] - x&#x5B;i];\r\n                    A&#x5B;i] = 1.0f \/ dx1;\r\n                    C&#x5B;i] = 1.0f \/ dx2;\r\n                    B&#x5B;i] = 2.0f * (A&#x5B;i] + C&#x5B;i]);\r\n                    dy1 = y&#x5B;i] - y&#x5B;i - 1];\r\n                    dy2 = y&#x5B;i + 1] - y&#x5B;i];\r\n                    r&#x5B;i] = 3 * (dy1 \/ (dx1 * dx1) + dy2 \/ (dx2 * dx2));\r\n                }\r\n\r\n                dx1 = x&#x5B;n - 1] - x&#x5B;n - 2];\r\n                dy1 = y&#x5B;n - 1] - y&#x5B;n - 2];\r\n                A&#x5B;n - 1] = 1.0f \/ dx1;\r\n                B&#x5B;n - 1] = 2.0f * A&#x5B;n - 1];\r\n                r&#x5B;n - 1] = 3 * (dy1 \/ (dx1 * dx1));\r\n\r\n                double&#x5B;] cPrime = new double&#x5B;n];\r\n                cPrime&#x5B;0] = C&#x5B;0] \/ B&#x5B;0];\r\n                for (int i = 1; i &lt; n; i++)\r\n                    cPrime&#x5B;i] = C&#x5B;i] \/ (B&#x5B;i] - cPrime&#x5B;i - 1] * A&#x5B;i]);\r\n\r\n                double&#x5B;] dPrime = new double&#x5B;n];\r\n                dPrime&#x5B;0] = r&#x5B;0] \/ B&#x5B;0];\r\n                for (int i = 1; i &lt; n; i++)\r\n                    dPrime&#x5B;i] = (r&#x5B;i] - dPrime&#x5B;i - 1] * A&#x5B;i]) \/ (B&#x5B;i] - cPrime&#x5B;i - 1] * A&#x5B;i]);\r\n\r\n                double&#x5B;] k = new double&#x5B;n];\r\n                k&#x5B;n - 1] = dPrime&#x5B;n - 1];\r\n                for (int i = n - 2; i &gt;= 0; i--)\r\n                    k&#x5B;i] = dPrime&#x5B;i] - cPrime&#x5B;i] * k&#x5B;i + 1];\r\n\r\n                for (int i = 1; i &lt; n; i++)\r\n                {\r\n                    dx1 = x&#x5B;i] - x&#x5B;i - 1];\r\n                    dy1 = y&#x5B;i] - y&#x5B;i - 1];\r\n                    a&#x5B;i - 1] = k&#x5B;i - 1] * dx1 - dy1;\r\n                    b&#x5B;i - 1] = -k&#x5B;i] * dx1 + dy1;\r\n                }\r\n\r\n                return (a, b);\r\n            }\r\n        }\r\n\r\n        public Form1()\r\n        {\r\n            InitializeComponent();\r\n        }\r\n\r\n        private void Form1_Load(object sender, EventArgs e)\r\n        {\r\n            Random rand = new(1268);\r\n            int pointCount = 15;\r\n            double&#x5B;] xs1 = DataGen.Consecutive(pointCount);\r\n            double&#x5B;] ys1 = new double&#x5B;pointCount];\r\n            for (int i = 1; i &lt; pointCount; i++)\r\n            {\r\n                \/\/xs1&#x5B;i] = xs1&#x5B;i - 1] + rand.NextDouble() - .5;\r\n                ys1&#x5B;i] = ys1&#x5B;i - 1] + rand.NextDouble() - .5;\r\n            }\r\n\r\n            \/\/ Use cubic interpolation to smooth the original data\r\n            (double&#x5B;] xs2, double&#x5B;] ys2) = Cubic.InterpolateXY(xs1, ys1, 200);\r\n\r\n            \/\/ Plot the original vs. interpolated data\r\n            var plt = new ScottPlot.Plot(900, 500);\r\n            plt.AddScatter(xs1, ys1, label: &quot;original&quot;, markerSize: 7);\r\n            plt.AddScatter(xs2, ys2, label: &quot;interpolated&quot;, markerSize: 3);\r\n            plt.Style(Style.Seaborn);\r\n            plt.Title(&quot;Cubic Spline&quot;);\r\n            plt.XLabel(&quot;x axis&quot;);\r\n            plt.YLabel(&quot;y axis&quot;);\r\n            plt.Legend();\r\n            plt.SaveFig(&quot;interpolation.png&quot;);\r\n            pictureBox1.ImageLocation = &quot;interpolation.png&quot;;\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<p><a href=\"https:\/\/gantovnik.com\/bio-tips\/2022\/11\/210-parametric-curve-in-3d-2-2-2-2-2-2-2-2-2-2-2-2-2-3-3-2-2-3-2-2-4-2-2-2-2\/interpolation-2\/\" rel=\"attachment wp-att-1650\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2022\/11\/interpolation.png?resize=900%2C500&#038;ssl=1\" alt=\"\" width=\"900\" height=\"500\" class=\"alignnone size-full wp-image-1650\" srcset=\"https:\/\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2022\/11\/interpolation.png 900w, https:\/\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2022\/11\/interpolation-480x267.png 480w\" sizes=\"(min-width: 0px) and (max-width: 480px) 480px, (min-width: 481px) 900px, 100vw\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Add ScottPlot.WinForms using Manage NuGet packages. Form1.cs using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows.Forms; using ScottPlot; namespace Spline { public partial class Form1 : Form { public static class Cubic { \/\/\/ &lt;summary&gt; \/\/\/ Generate a smooth (interpolated) curve that follows the path of the given X\/Y points \/\/\/ &lt;\/summary&gt; [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"nf_dc_page":"","_et_pb_use_builder":"","_et_pb_old_content":"","_et_gb_content_width":"","_lmt_disableupdate":"yes","_lmt_disable":"","jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[50],"tags":[],"class_list":["post-1649","post","type-post","status-publish","format-standard","hentry","category-c"],"modified_by":"gantovnik","jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"jetpack_shortlink":"https:\/\/wp.me\/p8bH0k-qB","jetpack_likes_enabled":true,"jetpack-related-posts":[{"id":1686,"url":"https:\/\/gantovnik.com\/bio-tips\/2022\/11\/210-parametric-curve-in-3d-2-2-2-2-2-2-2-2-2-2-2-2-2-3-3-2-2-3-2-2-4-2-2-2-2-2-3\/","url_meta":{"origin":1649,"position":0},"title":"#319 Scatter plot using ScottPlot.WinForms and C#","author":"gantovnik","date":"2022-11-29","format":false,"excerpt":"1) Install the ScottPlot.WinForms NuGet package 2) Drag a FormsPlot from the toolbox onto the form Form1.cs [code language=\"csharp\"] namespace WinFormsAppEx319 { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void formsPlot1_Load(object sender, EventArgs e) { \/\/ generate some random X\/Y data int pointCount =\u2026","rel":"","context":"In &quot;C#&quot;","block_context":{"text":"C#","link":"https:\/\/gantovnik.com\/bio-tips\/category\/c\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2022\/11\/ex319.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2022\/11\/ex319.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2022\/11\/ex319.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2022\/11\/ex319.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":1201,"url":"https:\/\/gantovnik.com\/bio-tips\/2021\/11\/210-parametric-curve-in-3d-2\/","url_meta":{"origin":1649,"position":1},"title":"#211 Lorenz attractor","author":"gantovnik","date":"2021-11-27","format":false,"excerpt":"[code language=\"python\"] import numpy as np import matplotlib.pyplot as plt def lorenz(x, y, z, s=10, r=28, b=2.667): \"\"\" Given: x, y, z: a point of interest in three dimensional space s, r, b: parameters defining the lorenz attractor Returns: x_dot, y_dot, z_dot: values of the lorenz attractor's partial derivatives at\u2026","rel":"","context":"In &quot;python&quot;","block_context":{"text":"python","link":"https:\/\/gantovnik.com\/bio-tips\/category\/python\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2021\/11\/ex211.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":2007,"url":"https:\/\/gantovnik.com\/bio-tips\/2024\/01\/401-add-labels-to-line-plot-in-python\/","url_meta":{"origin":1649,"position":2},"title":"#401 Add labels to line plot in python","author":"gantovnik","date":"2024-01-05","format":false,"excerpt":"[code language=\"python\"] import matplotlib.pyplot as plt import numpy as np plt.clf() # using some dummy data for this example n = 25 xs = np.linspace(1, 100, num=n) ys = np.random.normal(loc=3, scale=0.4, size=n) # 'bo-' means blue color, round points, solid lines plt.plot(xs,ys,'bo-') # zip joins x and y coordinates in\u2026","rel":"","context":"In &quot;matplotlib&quot;","block_context":{"text":"matplotlib","link":"https:\/\/gantovnik.com\/bio-tips\/category\/matplotlib\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2024\/01\/ex401.png?fit=640%2C480&ssl=1&resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2024\/01\/ex401.png?fit=640%2C480&ssl=1&resize=350%2C200 1x, https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2024\/01\/ex401.png?fit=640%2C480&ssl=1&resize=525%2C300 1.5x"},"classes":[]},{"id":1182,"url":"https:\/\/gantovnik.com\/bio-tips\/2021\/11\/204-mandelbrot-fractal-using-python-2-2\/","url_meta":{"origin":1649,"position":3},"title":"#206 Triangulation using matplotlib","author":"gantovnik","date":"2021-11-26","format":false,"excerpt":"[code language=\"python\"] import matplotlib.pyplot as plt from matplotlib.tri import Triangulation from matplotlib.patches import Polygon import numpy as np def update_polygon(tri): if tri == -1: points = [0, 0, 0] else: points = triang.triangles[tri] xs = triang.x[points] ys = triang.y[points] polygon.set_xy(np.column_stack([xs, ys])) def on_mouse_move(event): if event.inaxes is None: tri = -1\u2026","rel":"","context":"In &quot;python&quot;","block_context":{"text":"python","link":"https:\/\/gantovnik.com\/bio-tips\/category\/python\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2021\/11\/ex206.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":1596,"url":"https:\/\/gantovnik.com\/bio-tips\/2022\/10\/210-parametric-curve-in-3d-2-2-2-2-2-2-2-2-2-2-2-2-2-3-3-2-2-3-2-2-4\/","url_meta":{"origin":1649,"position":4},"title":"#305 Line plot using C#","author":"gantovnik","date":"2022-10-26","format":false,"excerpt":"Temperature.cs [code language=\"python\"] using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace WindowsFormsApp1 { public class Temperature { public string Location { get; set; } public decimal M1 { get; set; } public decimal M2 { get; set; } public decimal M3 { get; set; } public decimal\u2026","rel":"","context":"In &quot;C#&quot;","block_context":{"text":"C#","link":"https:\/\/gantovnik.com\/bio-tips\/category\/c\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2022\/10\/2022-10-26_041420-300x276.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":73,"url":"https:\/\/gantovnik.com\/bio-tips\/2018\/12\/spline-interpolation\/","url_meta":{"origin":1649,"position":5},"title":"Spline interpolation","author":"gantovnik","date":"2018-12-24","format":false,"excerpt":"import os import matplotlib.pyplot as plt import numpy as np from scipy.interpolate import spline os.chdir('\/home\/vg\/Downloads\/projects\/ex11') os.getcwd() plt.figure(figsize=(10,8)) xp = np.linspace(0,1,6) yp = np.sqrt(1-xp**2) xi = np.linspace(0,1,100) yi = np.interp(xi,xp,yp) ys = spline(xp,yp,xi) plt.plot(xp,yp,'o',label='given points',lw=2) plt.plot(xi,yi,'--',label='piecewise linear',lw=2) plt.plot(xi,ys,'-',label='spline',lw=2) plt.legend(loc='best') plt.grid() plt.xlabel('x') plt.ylabel('y') plt.title(r'Spline interpolation of $y=\\sqrt{1-x^2}$') plt.axis('scaled') plt.axis([0,1.2,0,1.2]) plt.savefig(\"example11.png\", dpi=100) plt.show()\u2026","rel":"","context":"In &quot;python&quot;","block_context":{"text":"python","link":"https:\/\/gantovnik.com\/bio-tips\/category\/python\/"},"img":{"alt_text":"example11","src":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2018\/12\/example11.png?resize=350%2C200","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2018\/12\/example11.png?resize=350%2C200 1x, https:\/\/i0.wp.com\/gantovnik.com\/bio-tips\/wp-content\/uploads\/2018\/12\/example11.png?resize=525%2C300 1.5x"},"classes":[]}],"_links":{"self":[{"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/posts\/1649","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/comments?post=1649"}],"version-history":[{"count":0,"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/posts\/1649\/revisions"}],"wp:attachment":[{"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/media?parent=1649"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/categories?post=1649"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/gantovnik.com\/bio-tips\/wp-json\/wp\/v2\/tags?post=1649"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}