public static class Spline
{
[System.Diagnostics.DebuggerDisplay("({X},{Y})")]
public partial struct Vec2
{
public float X, Y; public Vec2(float x, float y) { this.X = x; this.Y = y; } public static implicit operator PointF(Vec2 v) { return new PointF(v.X, v.Y); } public static implicit operator Vec2(PointF p) { return new Vec2(p.X, p.Y); } public static Vec2 operator +(Vec2 v1, Vec2 v2) { return new Vec2(v1.X + v2.X, v1.Y + v2.Y); } public static Vec2 operator -(Vec2 v1, Vec2 v2) { return new Vec2(v1.X - v2.X, v1.Y - v2.Y); } public static Vec2 operator *(Vec2 v, float f) { return new Vec2(v.X * f, v.Y * f); } public static Vec2 operator /(Vec2 v, float f) { return new Vec2(v.X / f, v.Y / f); } }
    
       /// <summary>
        /// '贝塞尔'内插。结果不包括头尾点
        /// </summary>
     public static PointF[] InterpolateBezier(PointF p0, PointF p1, PointF p2, PointF p3, int samples)
{
PointF[] result = new PointF[samples];
for (int i = ; i < samples; i++)
{
float t = (i + ) / (samples + 1.0f);
result[i] =
(Vec2)p0 * ( - t) * ( - t) * ( - t) +
(Vec2)p1 * ( * ( - t) * ( - t) * t) +
(Vec2)p2 * ( * ( - t) * t * t) +
(Vec2)p3 * (t * t * t);
}
return result;
} public static PointF[] InterpolateCardinalSpline(PointF p0, PointF p1, PointF p2, PointF p3, int samples)
{
const float tension = 0.5f;
Vec2 u = ((Vec2)p2 - (Vec2)p0) * (tension / ) + p1;
Vec2 v = ((Vec2)p1 - (Vec2)p3) * (tension / ) + p2;
return InterpolateBezier(p1, u, v, p2, samples);
}
    

      /// <summary>
      /// '基数样条'内插法。 points为通过点,samplesInSegment为两个样本点之间的内插数量。
      /// </summary>

public static PointF[] CardinalSpline(PointF[] points, int samplesInSegment)
{
List<PointF> result = new List<PointF>();
for (int i = ; i < points.Length - ; i++)
{
result.Add(points[i]);
result.AddRange(InterpolateCardinalSpline(
points[Math.Max(i - , )],
points[i],
points[i + ],
points[Math.Min(i + , points.Length - )],
samplesInSegment
));
}
result.Add(points[points.Length - ]);
return result.ToArray();
}
}

测试方法

public partial class Form1 : Form
{
protected override void OnPaint(PaintEventArgs e)
{
PointF[] ps = {new PointF(,), new PointF(, ), new PointF(, ), new PointF(,)};
// 系统的Graphics.DrawCurve,桃色
e.Graphics.DrawCurve(new Pen(Brushes.PeachPuff, ), ps);
// 自己取样,蓝色
e.Graphics.DrawLines(Pens.Blue, Spline.CardinalSpline(ps, ));
}
}

原文地址:https://blog.csdn.net/zheng558888/article/details/15816009

【转】Graphics.DrawCurve的算法的更多相关文章

  1. 戏说 .NET GDI+系列学习教程(二、Graphics类的方法)

    一.DrawBezier 画立体的贝尔塞曲线 private void frmGraphics_Paint(object sender, PaintEventArgs e) { Graphics g ...

  2. 从零开始学习GDI+ (二) 基本概念与基本操作

    从零开始学习GDI+ (一)我的第一个GDI+程序 上文给新手学习GDI+讲述了vs环境等的准备工作,并且可以直接用GDI+绘图了.本文开始,讲述的可能偏理论,建议学习的过程中大胆尝试,多使用API. ...

  3. [译]处理文本数据(scikit-learn 教程3)

    原文网址:http://scikit-learn.org/stable/tutorial/text_analytics/working_with_text_data.html 翻译:Tacey Won ...

  4. GDI+ 笔记

    1.GDI+模板 #include<windows.h> #include<GdiPlus.h> #include <time.h> #include <ma ...

  5. {Reship}{C#}{GDI+}GDI+画笔,线,区域类型

    =================================================================================== This article is ...

  6. Java实验三报告

    一.  实验内容 (一)敏捷开发与XP 摘要:一项实践在XP环境中成功使用的依据通过XP的法则呈现,包括:快速反馈.假设简单性.递增更改.提倡更改.优质工作.XP软件开发的基石是XP的活动,包括:编码 ...

  7. .Net验证码实现基础--Draw

    命名空间 using System.Draw; using System.Draw.Drawing2D; 在form等控件的 事件中 添加 paint事件 ///////画各种形状(空心)////// ...

  8. C#窗体程序画倾斜一定角度的椭圆

    using System;using System.Collections.Generic;using System.ComponentModel;using System.Data;using Sy ...

  9. GDI+: Curved Shapes

    原文 http://www.functionx.com/vcsharp2003/gdi/curves.htm Curves   Introduction to Curves   A curve is ...

随机推荐

  1. android 覆盖安装问题

    1.android中覆盖安装不会导致data/data/package下的数据被删除 2.数据库会有数据库的一套升级机制 3.sharepreference 不会被覆盖,如果在app中有使用Key记录 ...

  2. how to build jdk 9 source code

    http://hg.openjdk.java.net/build-infra/jdk9/raw-file/tip/README-builds.html#vs2013 http://royvanrijn ...

  3. 每日英语:Teens Are Still Developing Empathy Skills

    The teen years are often fraught with door-slamming, eye-rolling and seeming insensitivity, even by ...

  4. python(56):正则表达式积累

    来源:http://www.runoob.com/python/python-reg-expressions.html re.match函数 re.match 尝试从字符串的起始位置匹配一个模式,如果 ...

  5. Effective Spark RDDs with Alluxio【转】

    转自:http://kaimingwan.com/post/alluxio/effective-spark-rdds-with-alluxio 1. 介绍 2. 引言 3. Alluxio and S ...

  6. 【Android】Gesture Detector

    Gesture detector Android Touch Screen 与传统Click Touch Screen不同,会有一些手势(Gesture),例如Fling,Scroll等等. 这些Ge ...

  7. node的http请求

    //node的http服务 'use strict' var http = require('http') var server = http.createServer(function (reque ...

  8. Ubuntu 搜狗输入法崩溃 重启办法

    参考:https://www.findhao.net/res/786 打开终端,执行: pidof fcitx | xargs kill fcitx -r 上面两句意思就是kill fcitx的进程再 ...

  9. LeetCode: 【L4】N-Queens 解题报告

    [L4]N-Queens 解题报告 N-Queens Total Accepted: 16418 Total Submissions: 63309 My Submissions The n-queen ...

  10. AIX查看CPU、内存等信息

    AIX下查看CPUAIX操作系统AIX的硬件信息可以通过prtconf命令看到.1. 查看逻辑CPU个数#pmcycles -mCPU 0 runs at 4204 MHzCPU 1 runs at ...