Direct2D通过因此,想要使用Direct2D绘制一段通过指定点的曲线,比如Bezier曲线,必须借助于C#的代码可以很容易的转换成C++版本的,下面是我转换的一个用于Direct2D的绘制Bezier曲线的C++函数:

///

/// Refer to : http://www.codeproject.com/KB/graphics/BezierSpline.aspx

/// Solves a tridiagonal system for one of coordinates (x or y) of first Bezier control points.

///

/// Right hand side vector.

/// Solution vector.

void GetFirstControlPoints(

__in const std::vector& rhs,

__out std::vector& x )

{

ATLASSERT(rhs.size()==x.size());

int n = rhs.size();

std::vector tmp(n);    // Temp workspace.

FLOAT b = 2.0f;

x[0] = rhs[0] / b;

for (int i = 1; i < n; i++) // Decomposition and forward substitution.

{

tmp[i] = 1 / b;

b = (i < n-1 ? 4.0f : 3.5f) - tmp[i];

x[i] = (rhs[i] - x[i-1]) / b;

}

for (int i = 1; i < n; i++)

{

x[n-i-1] -= tmp[n-i] * x[n-i]; // Back substitution.

}

}

///

/// Refer to : http://www.codeproject.com/KB/graphics/BezierSpline.aspx

/// Get open-ended Bezier Spline Control Points.

///

/// Input Knot Bezier spline points.

/// Output First Control points array of knots.size()-1 length.

/// Output Second Control points array of knots.size()-1 length.

void GetCurveControlPoints(

__in const std::vector& knots,

__out std::vector& firstCtrlPt,

__out std::vector& secondCtrlPt )

{

ATLASSERT( (firstCtrlPt.size()==secondCtrlPt.size())

&& (knots.size()==firstCtrlPt.size()+1) );

int n = knots.size()-1;

ATLASSERT(n>=1);

if (n == 1)

{

// Special case: Bezier curve should be a straight line.

// 3P1 = 2P0 + P3

firstCtrlPt[0].x = (2 * knots[0].x + knots[1].x) / 3.0f;

firstCtrlPt[0].y = (2 * knots[0].y + knots[1].y) / 3.0f;

// P2 = 2P1 – P0

secondCtrlPt[0].x = 2 * firstCtrlPt[0].x - knots[0].x;

secondCtrlPt[0].y = 2 * firstCtrlPt[0].y - knots[0].y;

return;

}

// Calculate first Bezier control points

// Right hand side vector

std::vector rhs(n);

// Set right hand side X values

for (int i = 1; i < (n-1); ++i)

{

rhs[i] = 4 * knots[i].x + 2 * knots[i+1].x;

}

rhs[0] = knots[0].x + 2 * knots[1].x;

rhs[n-1] = (8 * knots[n-1].x + knots[n].x) / 2.0f;

// Get first control points X-values

std::vector x(n);

GetFirstControlPoints(rhs,x);

// Set right hand side Y values

for (int i = 1; i < (n-1); ++i)

{

rhs[i] = 4 * knots[i].y + 2 * knots[i+1].y;

}

rhs[0] = knots[0].y + 2 * knots[1].y;

rhs[n-1] = (8 * knots[n-1].y + knots[n].y) / 2.0f;

// Get first control points Y-values

std::vector y(n);

GetFirstControlPoints(rhs,y);

// Fill output arrays.

for (int i = 0; i < n; ++i)

{

// First control point

firstCtrlPt[i] = D2D1::Point2F(x[i],y[i]);

// Second control point

if (i < (n-1))

{

secondCtrlPt[i] = D2D1::Point2F(2 * knots[i+1].x - x[i+1], 2*knots[i+1].y-y[i+1]);

}

else

{

secondCtrlPt[i] = D2D1::Point2F((knots[n].x + x[n-1])/2, (knots[n].y+y[n-1])/2);

}

}

}

HRESULT CreateBezierSpline(

__in ID2D1Factory* pD2dFactory,

__in const std::vector& points,

__out ID2D1PathGeometry** ppPathGeometry )

{

CHECK_PTR(pD2dFactory);

CHECK_OUTPUT_PTR(ppPathGeometry);

ATLASSERT(points.size()>1);

int n = points.size();

std::vector firstCtrlPt(n-1);

std::vector secondCtrlPt(n-1);

GetCurveControlPoints(points,firstCtrlPt,secondCtrlPt);

HRESULT hr = pD2dFactory->CreatePathGeometry(ppPathGeometry);

CHECKHR(hr);

if (FAILED(hr))

return hr;

CComPtr spSink;

hr = (*ppPathGeometry)->Open(&spSink);

CHECKHR(hr);

if (SUCCEEDED(hr))

{

spSink->SetFillMode(D2D1_FILL_MODE_WINDING);

spSink->BeginFigure(points[0],D2D1_FIGURE_BEGIN_FILLED);

for (int i=1;i

spSink->AddBezier(D2D1::BezierSegment(firstCtrlPt[i-1],secondCtrlPt[i-1],points[i]));

spSink->EndFigure(D2D1_FIGURE_END_OPEN);

spSink->Close();

}

return hr;

}

下面是一个使用此函数绘制正弦函数的Sample,曲线的红点是曲线的控制点:

#pragma once

#include "stdafx.h"

#include

using D2D1::Point2F;

using D2D1::SizeU;

using D2D1::ColorF;

using D2D1::Matrix3x2F;

using D2D1::BezierSegment;

using D2D1::RectF;

#include

using std::vector;

#include

#include

class CMainWindow :

public CWindowImpl

{

public:

BEGIN_MSG_MAP(CMainWindow)

MSG_WM_PAINT(OnPaint)

MSG_WM_ERASEBKGND(OnEraseBkgnd)

MSG_WM_SIZE(OnSize)

MSG_WM_CREATE(OnCreate)

MSG_WM_DESTROY(OnDestroy)

END_MSG_MAP()

int OnCreate(LPCREATESTRUCT /*lpCreateStruct*/)

{

CreateDeviceIndependentResource();

CreateDeviceResource();

CreateCurve();

return 0;

}

void OnDestroy()

{

PostQuitMessage(0);

}

void OnPaint(CDCHandle)

{

CPaintDC dc(m_hWnd);

Render();

}

BOOL OnEraseBkgnd(CDCHandle dc)

{

return TRUE;    // we have erased the background

}

void OnSize(UINT /*nType*/, CSize size)

{

if (m_spHwndRT)

{

m_spHwndRT->Resize(SizeU(size.cx,size.cy));

CreateCurve();

}

}

private:

void Render()

{

if (!m_spHwndRT)

CreateDeviceResource();

m_spHwndRT->BeginDraw();

m_spHwndRT->Clear(ColorF(ColorF::CornflowerBlue));

m_spHwndRT->SetTransform(Matrix3x2F::Identity());

D2D1_SIZE_F size = m_spHwndRT->GetSize();

FLOAT width = size.width-50, height = size.height-50;

D2D1_MATRIX_3X2_F reflectY = Direct2DHelper::ReflectYMatrix();

D2D1_MATRIX_3X2_F translate = Matrix3x2F::Translation(size.width/2.0f,size.height/2.0f);

m_spHwndRT->SetTransform(reflectY*translate);

// draw coordinate axis

m_spSolidBrush->SetColor(ColorF(ColorF::Red));

m_spHwndRT->DrawLine(Point2F(-width*0.5f,0),Point2F(width*0.5f,0),m_spSolidBrush,2.0f);

m_spSolidBrush->SetColor(ColorF(ColorF::DarkGreen));

m_spHwndRT->DrawLine(Point2F(0,-height*0.5f),Point2F(0,height*0.5f),m_spSolidBrush,2.0f);

// draw curve

m_spSolidBrush->SetColor(ColorF(ColorF::Blue));

m_spHwndRT->DrawGeometry(m_spPathGeometry,m_spSolidBrush,1.0f);

// draw point marks

m_spSolidBrush->SetColor(ColorF(ColorF::Red));

for (auto p=m_Points.cbegin();p!=m_Points.cend();p++)

{

Direct2DHelper::DrawRectPoint(m_spHwndRT,m_spSolidBrush,(*p),5.0f);

}

HRESULT hr = m_spHwndRT->EndDraw();

if (hr == D2DERR_RECREATE_TARGET)

DiscardDeviceResource();

}

void CreateDeviceIndependentResource()

{

Direct2DHelper::CreateD2D1Factory(&m_spD2dFactory);

}

void CreateDeviceResource()

{

CRect rc;

GetClientRect(&rc);

CHECK_PTR(m_spD2dFactory);

IFR(m_spD2dFactory->CreateHwndRenderTarget(

D2D1::RenderTargetProperties(),

D2D1::HwndRenderTargetProperties(m_hWnd,SizeU(rc.Width(),rc.Height())),

&m_spHwndRT));

IFR(m_spHwndRT->CreateSolidColorBrush(ColorF(ColorF::Red),&m_spSolidBrush));

}

void DiscardDeviceResource()

{

m_spSolidBrush.Release();

m_spHwndRT.Release();

}

void CreateCurve()

{

if (!m_spHwndRT)

return;

if (m_spPathGeometry)

{

m_spPathGeometry.Release();

m_Points.clear();

}

const int ptCount = 100;

D2D1_SIZE_F size = m_spHwndRT->GetSize();

FLOAT width = size.width-50.0f, height = size.height*0.4f;

#define SIN_CURVE

#ifdef SIN_CURVE    // create sin curve

FLOAT factor = static_cast(4.0f*M_PI/width);

FLOAT x = -width*0.5f, y = 0, dx = width/ptCount;

for (int i=0;i

{

y = height*sin(factor*x);

m_Points.push_back(Point2F(x,y));

x += dx;

}

#else                // create normal distribute curve

FLOAT factor = 10.0f/width;

FLOAT x = -width*0.5f, y = 0, dx = width/ptCount;

boost::math::normal nd;

for (int i=0;i

{

y = height*static_cast(boost::math::pdf(nd,factor*x));

m_Points.push_back(Point2F(x,y));

x += dx;

}

#endif // SIN_CURVE

// create Bezier spline

Direct2DHelper::CreateBezierSpline(m_spD2dFactory,m_Points,&m_spPathGeometry);

CHECK_PTR(m_spPathGeometry);

}

private:

CComPtr m_spD2dFactory;

CComPtr m_spHwndRT;

CComPtr m_spSolidBrush;

CComPtr m_spPathGeometry;

vector m_Points;

};

java画bezier曲线,解析在Direct2D中画Bezier曲线的实现方法相关推荐

  1. VC++ 利用MFC的CWindowDC类实现画线功能 在桌面窗口中画线 绘制彩色线条 CPen nPenStyle nWidth crColor

    目录 利用MFC的CWindowDC类实现画线功能 在桌面窗口中画线 绘制彩色线条 CPen nPenStyle nWidth crColor 接上:VC++ 绘制线条 OnLButtonDown函数 ...

  2. [重学Java基础][Java IO流][Exter.2]IO流中几种不同的读写方法的区别

    [重学Java基础][Java IO流][Exter.2]IO流中几种不同的读写方法的区别 Read 读入方法 read(): 一般是这种形式 public int read() 1.从流数据中读取的 ...

  3. python绘制缓和曲线_在cad中画缓和曲线的绘制方法

    缓和曲线具有以下作用:曲率连续变化,便于车辆遵循:离心加速度逐渐变化,旅客感觉舒适:超高横坡度及加宽逐渐变化,行车更加稳定:与圆曲线配合,增加线形美观.故,缓和曲线在公路.桥梁.铁路及高速铁路中广泛采 ...

  4. java web配置dll文件_JavaWeb项目中dll文件动态加载方法解析(详细步骤)

    相信很多做Java的朋友都有过用Java调用JNI实现调用C或C++方法的经历,那么Java Web中又如何实现DLL/SO文件的动态加载方法呢.今天就给大家带来一篇JAVA Web项目中DLL/SO ...

  5. Gson解析JSON数据中动态未知字段key的方法

    转载自:https://blog.csdn.net/jdsjlzx/article/details/76785239 有时在解析json数据中的字段key是动态可变的时候,由于Gson是使用静态注解的 ...

  6. unity 控制点 贝塞尔曲线_在Unity中使用贝塞尔曲线(转)

    鼎鼎大名的贝塞尔曲线相信大家都耳熟能详.这两天因为工作的原因需要将贝塞尔曲线加在工程中,那么MOMO迅速的研究了一下成果就分享给大家了哦.贝塞尔曲线的原理是由两个点构成的任意角度的曲线,这两个点一个是 ...

  7. python画三维立体图-如何在论文中画出漂亮的插图?

    ----2020.08.07增---- 看到评论区有人说"没代码没教程所以没帮助"-- 好吧,我寻思链接.参考资料都在回答中给出来了呀(可能不够明显?) 于是,重新整理.注释了一下 ...

  8. java 判断手机运营商_Java开发中识别手机运营商的方法

    在Java开发中程序需要根据用户输入的号码判断运营商,这该怎么实现呢?而我们需要根据不同的运营商进行相应的处理,下面是爱站技术频道小编介绍的Java开发中识别手机运营商的方法. js实现方法: var ...

  9. java数组删除元素_java删除数组中的某一个元素的方法

    下面小编就为大家带来一篇java删除数组中的某一个元素的方法.小编觉得挺不错的,现在就分享给大家,也给大家做个参考.一起跟随小编过来看看吧 实例如下: package org.company.proj ...

最新文章

  1. Oracle ASM -- disk header
  2. 远程服务器系统管理,如何远程管理服务器系统(转载)
  3. 20110609 搭域控,布线,设计网络,杂事一堆啊
  4. Java之Socket与HTTP区别
  5. C# 利用DotRas 操作adsl
  6. windows键按了没反应_windows快捷键使用 - 小怜
  7. ultraedit 运行的是试用模式_单元测试 —— 前后端分离开发模式下后端质量的保证...
  8. Linux socket can例程C++版本
  9. 通信原理实践(一)——音频信号处理
  10. 学习 nltk —— TF-IDF
  11. HDU 3949 XOR (线性基第k小)题解
  12. esp8266等待上电同步_[网络篇]ESP8266-NonOS学习笔记(三)之TCP通信Serverlt;-gt;Client
  13. 【大一期末项目】qqclienkey利用:基于qqclientkey的纯c++项目实践
  14. 自己编写DLL文件——注册——VB工程引用——标准EXE调用(含例子)
  15. 易行长指出了利率市场化”最后一枪“
  16. PS如何制作火焰效果图特效步骤教程
  17. word转chm文件
  18. 你应该知道的 89 个操作系统核心概念
  19. 数据结构(3)常见的树
  20. linux修改密码时候提示太简单了怎么办,linux修改密码

热门文章

  1. 【Android驱动】闪光灯flashlight的记录
  2. 前端高频面试题目 -- 15k级别
  3. Ensemble of the Deep Convolutional Network for Multiclass of Plant Disease Classi¯cation Using Leaf
  4. Fragment CATION2安卓
  5. 服务器发送了一个意外的数据包 received 3_肝不好,身体会发出3个信号求救,每天吃1物,肝想不好都难!...
  6. JAVA基础-U7 面向对象编程(基础部分)-递归
  7. 动态规划思想以及常见应用
  8. 解决常用浏览器上传与下载文件中问乱码问题
  9. 最“全”新零售运维保障解决方案——阿里巴巴GOC技术实践经验独家曝光
  10. 不可错过的资源下载。。学无止境呀。。