Advertisement
csaki

deCasteljau algoritmus

Nov 19th, 2013
230
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 5.39 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Data;
  5. using System.Drawing;
  6. using System.Linq;
  7. using System.Text;
  8. using System.Windows.Forms;
  9.  
  10. namespace deCasteljau
  11. {
  12.     public partial class Form1 : Form
  13.     {
  14.         Graphics g;
  15.         public Form1()
  16.         {
  17.             InitializeComponent();
  18.             g = CreateGraphics();
  19.             MouseUp += new MouseEventHandler(Form1_MouseUp);
  20.             MouseDown +=new MouseEventHandler(Form1_MouseDown);
  21.             MouseMove +=new MouseEventHandler(Form1_MouseMove);
  22.         }
  23.  
  24.         const int DB = 200;
  25.         static PointF[] kp;
  26.         static List<PointF> pontok = new List<PointF>();
  27.         static int R = 4;
  28.         static bool megvan_ = false;
  29.         static int pontIndex = 0;
  30.  
  31.         private PointF deCasteljau_iter2(float u)
  32.         {
  33.             int n = kp.Length - 1;
  34.             PointF[] Q = new PointF[n + 1];
  35.             for (int i = 0; i <= n; i++)
  36.                 Q[i] = kp[i];
  37.             for (int r = 1; r <= n; r++)
  38.                 for (int i = 0; i <= n - r; i++)
  39.                     Q[i] = new PointF((1 - u) * Q[i].X + u * Q[i + 1].X, (1 - u) * Q[i].Y + u * Q[i + 1].Y);
  40.  
  41.             return Q[0];
  42.         }
  43.  
  44.         private PointF deCasteljau_rek(int i, int r, float u)
  45.         {
  46.             if (r == 0) { return kp[i]; }
  47.             else
  48.             {
  49.                 PointF P1 = deCasteljau_rek(i, r - 1, u);
  50.                 PointF P2 = deCasteljau_rek(i + 1, r - 1, u);
  51.                 return new PointF(((1 - u) * P1.X + u * P2.X), ((1 - u) * P1.Y + u * P2.Y));
  52.             }
  53.         }
  54.  
  55.         private void drawDeCasteljau_iter()
  56.         {
  57.             //Invalidate();
  58.             //Update();
  59.             Graphics myG = CreateGraphics();
  60.             int db = DB;
  61.             double A = 0;
  62.             double b = 1;
  63.             double h = Math.Abs(b - A) / db;//h:lépésköz, db:a görbe pontjainak a szama
  64.             double u = A;
  65.             PointF[] pontok = new PointF[db + 1];//a görbe pontjai
  66.             for (int i = 0; i <= db; i++)
  67.             {
  68.                 // pontok[i] = deCasteljau(0, kp.Length - 1, (float)u);
  69.                 pontok[i] = deCasteljau_iter2((float)u);
  70.                 u += h;
  71.             }
  72.  
  73.             myG.DrawLines(new Pen(Color.Blue), pontok);
  74.         }
  75.  
  76.         private void drawDeCasteljau()
  77.         {
  78.             //Invalidate();
  79.             //Update();
  80.             Graphics myG = CreateGraphics();
  81.             int db = DB;
  82.             double A = 0;
  83.             double b = 1;
  84.             double h = Math.Abs(b - A) / db;//h:lépésköz, db:a görbe pontjainak a szama
  85.             double u = A;
  86.             PointF[] pontok = new PointF[db + 1];//a görbe pontjai
  87.             for (int i = 0; i <= db; i++)
  88.             {
  89.                 // pontok[i] = deCasteljau(0, kp.Length - 1, (float)u);
  90.                 pontok[i] = Bezier((float)u);
  91.                 u += h;
  92.             }
  93.  
  94.             myG.DrawLines(new Pen(Color.Blue), pontok);
  95.         }
  96.  
  97.         private PointF Bezier(float u)
  98.         {
  99.             int n = kp.Length - 1;
  100.             PointF point = new PointF();
  101.             for (int i = 0; i <= n; i++)
  102.             {
  103.                 float b = Bernstein((double)i, (double)n, u);
  104.                 point.X += kp[i].X * b;
  105.                 point.Y += kp[i].Y * b;
  106.             }
  107.             return point;
  108.         }
  109.  
  110.         private int Fact(double n)
  111.         {
  112.             int x = 1;
  113.             for (int i = 1; i <= n; i++)
  114.                 x *= i;
  115.             return x;
  116.         }
  117.  
  118.         private float Bernstein(double i, double n, float u)
  119.         {
  120.             if (i < 0 || i > n) return 0;
  121.  
  122.             return (float)(Fact(n) / (Fact(i) * Fact(n - i)) * Math.Pow(u, i) * Math.Pow(1 - u, n - i));
  123.         }
  124.  
  125.         private void Rajz()
  126.         {
  127.             kp = new PointF[pontok.Count];
  128.             for (int i = 0; i < kp.Length; i++)
  129.                 kp[i] = pontok[i];
  130.              
  131.             g.DrawLines(new Pen(Color.Black), kp);
  132.  
  133.             drawDeCasteljau();
  134.         }
  135.  
  136.         private void Form1_MouseUp(object sender, MouseEventArgs e)
  137.         {
  138.              
  139.             if (!megvan_) { pontok.Add(new PointF(e.X, e.Y)); }
  140.             Invalidate();
  141.             Update();
  142.             foreach (PointF x in pontok)
  143.             {
  144.                 g.DrawEllipse(Pens.Red, x.X - R, x.Y - R, 2 * R, 2 * R);
  145.             }
  146.  
  147.             if (pontok.Count >= 3) Rajz();
  148.             megvan_ = false;
  149.         }
  150.  
  151.  
  152.  
  153.         private void Form1_MouseDown(object sender, MouseEventArgs e)
  154.         {
  155.             for (int i = 0; i < pontok.Count; i++)
  156.             {
  157.                 PointF x = pontok[i];
  158.                 if (e.X > x.X - R && e.X < x.X + R && e.Y > x.Y - R && e.Y < x.Y + R)
  159.                 {
  160.                     pontIndex = i;
  161.                     megvan_ = true;
  162.                     break;
  163.                 }
  164.             }
  165.  
  166.             if (e.Button == System.Windows.Forms.MouseButtons.Right)
  167.             {
  168.                 pontok.RemoveAt(pontIndex);
  169.             }
  170.         }
  171.  
  172.  
  173.         private void Form1_MouseMove(object sender, MouseEventArgs e)
  174.         {
  175.             if (megvan_)
  176.             {
  177.                 pontok[pontIndex] = new PointF(e.X, e.Y);
  178.                 Invalidate();
  179.                 Update();
  180.                 Rajz();
  181.             }
  182.         }
  183.     }
  184. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement