思使给笔迹能够来笔锋的意义。我娘喜悦地东山再起我说。苦逼的自己及了大学才对编程有了还进一步的认。

通过前方两篇稿子,
我们曾缓解了于手记笔迹中的平缓问题. 本篇将执教如何让手写笔迹能够发生笔锋效果.

文|七九月份猫及CD

2018 我来啦!

 


 

告别了17,迎来了初的等同年。

本人又蛮了同春,有时候听到别人突然称起年,我都见面遗忘了自己多异常了。

本以为自己已经杀怪了,一算,额还非常年轻的。

苦逼的本人上了大学才对编程有矣更进一步的认识,这几乎年下来,对编程的感觉要不错的。

而大学里的教学还是基础之,没有呀会益的念,C
/C++基本上还是拿基础之语法什么的说道了了即没了。

学了Python和Java才对有的库函数有些认识。

真诚感到好在高等学校之时刻不够,甚至能无可知招来打工作还无必然。

如今起了方向,想主学JAVA
先找到工作加以,然后直接自学C++、Python、UE4。

本身就属于那种对呀还很谢谢兴趣,但是又休能够死劲按在一个模仿的主。

然在新的同一年里,我思念改这点,我晓得改变并无易于,但是不转实在难受。

免更改会非常的…..

怀念只要受笔迹能够出笔锋的功能, 那么整个笔迹肯定不可能是相当方便的.也就是说,
要为咱们绘制出来的墨迹线条必须要来必然的粗细变化.

母亲手中线

Le vent se lève, il faut tenter de vivre

JAVA是无是最为轻找到工作之?大家谈论。


拥有人都能生当然的想到 粗细变化的法则: 活动快的地方得线条应该重周密,
运动慢的的地方细条应该更粗
.是的, 这是极度中心的规律,
这个想法完全正确.

昨日自我接受妈妈的微信信息,大概是发挥梦到自身活动不行远之程,谈恋爱谈的百般麻烦。叮嘱自己而照料好温馨,按时吃饭,不要感冒。

 其实效仿什么和产生工作尚未尽要命影响,学号了才是真理。

说点题外话, 最近于扣押机器上, 神经网络模型中来一个给:激活函数的物,
它的来意就是为了吃神经网络具有分层的非线性映射学习之力量,
若完全是线性的, 在处理某些复杂情况时,得到的结果碰头很糟糕糕.

自己说,妈,我思念吃而包之饺子了。

 追求卓越,成功自会随着而来。

一如既往, 我们于拍卖手写笔迹的时,
线条的粗细也未该全同速度是同样栽线性的扭转关系,.

自身妈喜悦地还原我说,等公回去,妈天天被你保证。

  听从内心。

才是自个儿该选的征程。

 

PS:终于找到论坛了。

实则,
如果完全以同等种植线性的变动关系,
绘制出来的线条会扣押起很想得到(亲测完全如此).

由小到充分我们下要是过年过节我妈都见面说,洗手,我们今天包饺子。春节内来了亲戚朋友,吃了却炒菜,我妈妈总要预备饺子。在自身妈妈眼里,这是重视,也是礼待。

就此, 在盘算线条粗细的当儿, 在依照”速度越快的地方,线条更仔细;
速度缓慢的地方,线条更有些” 这同样长长的基本准则的前提下,
也应有根据部分具体情况, 让线的粗细变化所有”非线性”的能力.

用,吃饺子是其表达好之平等种方式。

 

尚并未达标大学以前,我跟妹妹几乎各个半周到回家一坏,她还见面让咱们保证一顿饺子吃,如果有事忙没顾上,她会念叨好几软。上大学后,放假返家,她还设给我们第一搁浅吃饺子。离小时的前天,妈妈也会见管饺子。迎回送活动,以饺子开始,以饺子了。

下我根据手写的其实情形,提出有题目, 大家可略思考一下:

保险饺子是同一项大得意麻烦的从事,每一样次于我妈妈都使和谐剁肉,坚决不要绞肉机。她底理由是机器将出来的非热。饺子馅里的菜她也如自己一点一点剁的碎碎的。自己和面,擀皮,捏成各式各样的样子。

1) 假设我们的计量线条笔宽的函数就是:
W_current = k * s,
其中s为当前线笔迹点运动的快慢,
k为拿速映射为笔宽的一个固定系数.

用户移动时,
得到了3独相邻之触发依次分别吗:a,b,c, 在ab线段, 移动速度接近无限好,
而在bc段移动的速最好接近0,

其实, 在手记笔迹的时段,完全有或
前相同段落移动速度非常抢, 到下一段距离的时节,
移动速度就顿时变得要命缓慢了.

自只是将可能遇见的情事进行了夸张, 那么,
在这种情形下,我们应当什么处理线条的粗细呢?

自我和胞妹不思妈妈辛苦,从小就是跟着帮忙,如今我们曾经好单独完成由剁馅到饺子下锅的尽过程了。但是妈妈的寓意,是仿不来的。

2) 同样借而3只点, 两长条线ab, bc, cd,
并且假设ab, bc有足的长短,
使得我们计算出来的宽窄变化看起吧是比较客观之,
这样说或许不太好理解.

推选个栗子: ab, bc的线条长度还为100独像素,
计算出ab线段线条的升幅应该是5, bc线段的线条宽度该是10,

打真正手写的动静来拘禁,
200单如素长度的墨迹, 只发生5只像从的宽变化,这是一心成立之.

那么,如果我们之所以宽度5来绘制线段ab,
然后用宽度10来绘制线段bc, 我们绘制出的字迹是什么法的?
(发挥一下想象力)

饺子

3) 在实际手写的状况下,
文字的笔迹的笔锋主要反映于文的什么样部位?

在家的时节,过年过节都吃饺子,平时隔三差五也凭着饺子,不免觉得腻。饺子上桌的时光,我和胞妹最多吃十五独就是下未了口了。在他乡学习常常,会专门怀念念妈妈做的饺子。去餐饮店请同样客饺子,吃几人数便以为味道不对准。速冻饺子和妈妈做的相比差的是十万八千里。

下面我们分别讨论这3个问题.
问题一:
设完全按照线性函数W_current = k * s
来算宽度, 相邻两端线条的笔宽变化出或很坏,
大到超过了我们可以的纳范围.

为此我们着想通过某种方式来界定这种突然的更动,
让线宽度之浮动看起再次自然.

下面是自家更正后的测算线条宽度之函数:
W_current =

本身怀念过为什么妈妈总喜欢吃咱们吃饺子。他们老年代,总是吃不满足,能吃到面就正确了,饺子那就是是过年啊无自然吃得。妈妈的小时候和年轻还过的生麻烦。现在想吃就足以吃到了,但是当它们衷心,饺子都成了一样种礼遇。不单单是一旋转食物那么粗略。

  W_previous

自我以为它爱好在咱们在家的时候保证饺子还有一个因是,我们得边包饺子边说说属于妈妈跟姑娘中间的那种心里话。吃饭和做饭的时刻是交流的好时。我们平素能陪伴他们的工夫最少了,他们顾念如果打造关键争分夺秒的跟我们相处。

  • min( abs(k*s – W_previous), distance * K_width_unit_change)
    (k * s-W_previous) >=
    0

      W_previous
  • min( abs(k*s – W_previous), distance * K_width_unit_change)
    (k * s-W_previous) <
    0

      W_current      
    当前线的大幅度
      W_previous    与目前线相邻的先头同一久线段的升幅
      distance
             当前线的长
      w_k
            设定的一个恒定阈值,表示:单位去外,
    笔迹的线宽度可以扭转的绝老量.
      distance *
    w_k     即为目前线的长短内, 笔宽得相对于前同一长长的线段笔宽的根基及,
    最多克变宽或者可以转移狭窄多少.
    这个函数大多引入了2单变量(前一样修线段的宽窄,
    还有当前之线条的距离), 每当盘算线条宽度时,
    考虑了再度多的可能性
    .
    增加了相同种非线性的浮动机制,
    min.这个min就是咱们的”激活函数”.让我们的丝宽不再只具有线性的变迁了.

    而今, 这个算线宽的函数,看起就于完美了.

咱们到底想着好努力,等我们以城池购买了房屋就是把他们收身边,我们纪念赚了钱便牵动他们失去旅行,我们想叫她们进货好的保健品让他俩身体健康。可是咱们倒是忽视了无限中心的,他们需要我们吸纳他们表达出来的轻跟温暖,他们用有的时间跟我们说说近况、工作与恋爱,他们期待而会常于打电话报告她们你整都好,他们年龄老了公得多关心他们的身体,不然他们非舒适也未见面告诉你,担心耽误你得学或者工作,担心你们花钱。你看,他们总是想拿最好好不过圆的容易被我们,却为接连提心吊胆拖延累我们,给咱们造成负担。

问题二:
咱们一直看一个自我有意做得比较坏的示范图:

自家发觉及他们老矣凡当爸爸头上突兀多矣广大白发,年轻时美的妈妈脸上已经满皱纹。我无限亮树欲静而风不止、子欲养而亲不待这句话了。我会每周都打一个对讲机被她们,离开家的时节让爸妈洗脚,剪指甲,去丢下上的死皮,看到有些爸妈没有吃了之哪怕市来寄托回家,或者买一个暖手宝,或者买一个新的剃须刀。

图片 1

青少年,你别认为你还年轻,父母便还没有尽。等你发出钱了,他们即使始终矣,你进的好多吃的他们还咬不动了,你带他们看景他们吧体力跟不上了。而且若还是会忙不迭,你不光要忙于工作,你还要看孩子,照顾你得小家庭。你才见面越加忙。

虽此效应大致看起看还实施, 作为同誉为追求完美的程序员,
始终觉得呀地方不对准劲.

与其,从枝叶做打,从陪伴开始。陪他们美好做同样停顿饭,吃一样停顿饭,看看电视要遛遛狗。让他们觉得你用他们,就是最最好之易了。

这就是说我们更把这个题材放到平种最的情事:

妈妈,我怀念吃你包的饺子了。

 

图片 2

诸如此类问题虽非常明白了.

自家解决是题材之章程是:以微分的琢磨,
把线段再次精心分成多条子线段,
宽度之浮动都匀的布在这些细分的子线段上.

这般, 我们的线宽度变化看起便越自然了.

 

问题三:

在平时之写过程中,
笔锋主要反映在画的开始位置,
转角位置, 和画了之位置.

在笔迹转角的职位体现出笔锋看起比艰难,
但是于笔迹开始同终止之地方做一些篇章或于容易.

本人之具体做法是这么, 在笔迹开始的前5独点(这个’5′,
是我无想出来的, 也只是4,6,7,8), 让笔迹的宽细变化更明朗

当笔迹的利落位置, 不管之前的线条宽度是不怎么,
都让其当末位置收缩为极小笔宽. 

还好之说辞我呢说不出来为什么,应该是属于程序员的第七谢谢吧,
感觉这样做会比好. 而且事实证明效果实在不错.

骨子里这里为体现了”非线性”变化之思辨,
因为自己看就同碰比较主要, 所以单独提出来.

 

缓解上述3个问题, 离这个算法的中标,
就还不一有细节之问题了.(虽然是细节问题,
但是以下即几个待专注的细节死坏坏主要,
说三遍!!!!!!!)

下面我就算无进关子, 直接报告大家用专注的地方:

1)  在实际上的状态遇, 移动
定位装置(鼠标,手写笔,或者触摸屏)时,
设备发送给咱们的mouse_move消息会非常的多, 需要开一个

  时间阈值,
比如前同一不良信息及即无异不良信息之间隔时间小于30毫秒, 就拿这个点废弃掉. 否则,
点太多, 每个都处理, 基本上还是剩下的计算..

2) 在事实上状况遇, 需要设置一个偏离阈值,
当本次获得的触发, 到直达一个点的离开小于是阈值时, 把这个点舍弃丢,
距离最接近, 也是多余的计算.

以上内容, 
差不多就是手写笔迹算法中持有术难关和内需专注的底细了.

 

下面将C++实现的源代码分享给大家, 其中z_math.h,
z_math.c使用纯c实现,除了c标准库,没有其余任何借助,可以不要压力之移植到各个支持c/c++语言的外平台.

z_math是算法的为主实现有:

  1 /*
  2 =====================================================================================
  3  *       Filename:  z_math.h
  4  *    Description:  
  5  *        Version:  2.0
  6  *        Created:  06/23/2016 14:53:43
  7  *       Revision:  none
  8  *       Compiler:  gcc
  9  *         Author:  zl(88911562@qq.com), 
 10  *   Organization:  
 11  * =====================================================================================
 12  */
 13 //_________________________________
 14 // stl on mac location is:
 15 // /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include/c++/v1
 16 // Mac OS X 10.9+ no longer uses GCC/libstdc++ but uses libc++ and Clang.
 17 //---------------------------------
 18 //td c++ (STL, streams, ...) : Modified libstdc++ headers for use with ctags 
 19 //use ctags for c++(stl,streams....)
 20 //www.vim.org/scripts/script.php?script_id=2358
 21 //ctags -R --c++-kinds=+p --fields=+ias --extra=+q --language-force=c++ cpp_src 
 22 //sudo ctags -R --c++-kinds=+p --fields=+ias --extra=+q --language-force=c++ ./
 23 //================================= */
 24 #ifndef z_math_h_
 25 #define z_math_h_
 26 
 27 #ifdef __cplusplus
 28 extern "C" {
 29 #endif
 30     
 31 #include <stdint.h>
 32 
 33 typedef struct z_point_s  z_point;
 34 typedef struct z_fpoint_s z_fpoint;
 35 typedef struct z_ipoint_s z_ipoint;
 36 typedef struct z_fpoint_array_s z_fpoint_array;
 37 typedef struct z_fpoint_arraylist_node_s  z_fpoint_arraylist_node;
 38 typedef struct z_fpoint_arraylist_s z_fpoint_arraylist;
 39 
 40 struct z_point_s {
 41     float x, y;
 42 };
 43 
 44 struct z_fpoint_s{
 45     z_point p;
 46     float w;
 47 };
 48 
 49 struct z_ipoint_s {
 50     z_point p;
 51     int64_t t;
 52 };
 53 
 54 struct z_fpoint_array_s {
 55     z_fpoint *point;
 56     float maxwidth;
 57     float minwidth;
 58     int ref;
 59     int len;
 60     int cap;
 61 
 62     z_point last_point;
 63     float last_width;
 64     int64_t last_ms;
 65 };
 66 
 67 struct z_fpoint_arraylist_node_s {
 68     z_fpoint_array *a;
 69     z_fpoint_arraylist_node *n;
 70 };
 71 
 72 struct z_fpoint_arraylist_s {
 73     int ref;
 74     z_fpoint_arraylist_node *first;
 75     z_fpoint_arraylist_node *end;
 76     z_fpoint_arraylist_node *cur;
 77 };
 78 
 79 z_fpoint_array *z_keep_fpoint_array(z_fpoint_array *a);
 80 void z_drop_fpoint_array(z_fpoint_array *a);
 81 
 82 z_fpoint_arraylist* z_keep_fpoint_arraylist(z_fpoint_arraylist *l);
 83 void z_drop_fpoint_arraylist(z_fpoint_arraylist *l);
 84 
 85 z_fpoint_array *z_new_fpoint_array(int initsize, float maxwidth, float minwidth);
 86 z_fpoint_array *z_resize_fpoints_array(z_fpoint_array* a, int size);
 87 
 88 z_fpoint_arraylist *z_new_fpoint_arraylist();
 89 void z_fpoint_arraylist_append(z_fpoint_arraylist *l, z_fpoint_array *a);
 90 // must be drop after used
 91 z_fpoint_array *z_fpoint_arraylist_append_new(z_fpoint_arraylist *l, float maxwidth, float minwidth);
 92 void z_fpoint_arraylist_removelast(z_fpoint_arraylist *l);
 93 
 94 float z_movespeed(z_ipoint s, z_ipoint e);
 95 float z_distance(z_point s, z_point e);
 96 void  z_fpoint_add_xyw(z_fpoint_array *a, float x, float y, float w);
 97 void  z_fpoint_add(z_fpoint_array *a, z_fpoint p);
 98 void  z_fpoint_differential_add(z_fpoint_array *a, z_fpoint p);
 99 void  z_square_bezier(z_fpoint_array *a, z_fpoint b, z_point c, z_fpoint e);
100 float z_linewidth(z_ipoint b, z_ipoint e, float w, float step);
101 
102 float z_insert_point(z_fpoint_array *arr, z_point point);
103 void  z_insert_last_point(z_fpoint_array *arr, z_point e);
104 
105 
106 typedef struct z_list_node_s z_list_node;
107 struct z_list_node_s {
108     void *data; 
109     z_list_node *n;
110     z_list_node *p;
111 }; 
112 typedef void*(*z_list_node_alloc_fun)();
113 typedef void(*z_list_node_drop_fun) (void *data);
114 
115 
116 struct z_list_s {
117     z_list_node_alloc_fun alloc;
118     z_list_node_drop_fun  drop;
119     z_list_node *first;
120     z_list_node *last;
121 };
122 typedef struct z_list_s z_list;
123 
124 z_list *z_list_new(z_list_node_alloc_fun allocfun, z_list_node_drop_fun dropfun);
125 void *z_list_append_new(z_list *zlist);
126 void *z_list_remove_last(z_list *zlist);
127 void z_list_clear(z_list *zlist);
128 void z_list_free(z_list *zlist);
129 
130 /* digest must be 33 char size  */
131 // void z_text_md5(const char* str, char *digest);
132 
133 #ifdef __cplusplus
134 }
135 #endif
136 
137 #endif

  1 /*
  2 =====================================================================================
  3  *       Filename:  z_math.c
  4  *    Description:
  5  *        Version:  1.0
  6  *        Created:  06/23/2016 14:53:43
  7  *       Revision:  none
  8  *       Compiler:  gcc
  9  *         Author:  zl(88911562@qq.com), 
 10  *   Organization:  
 11  * =====================================================================================
 12  */
 13 #include <math.h>
 14 #include <stdio.h>
 15 #include <string.h>
 16 #include <stdlib.h>
 17 #include <time.h> 
 18 #include "z_math.h"
 19 
 20 #define z_malloc_struct(t) (t*)calloc(1, sizeof(t))
 21 static void* z_malloc_array(unsigned int count, unsigned int size);
 22 static void* z_resize_array(void *p, size_t count, size_t size);
 23 
 24 static void z_fpoint_array_set_last_info(z_fpoint_array *arr, z_point last_point, float last_width);
 25 
 26 /***************************** mac stdlib location:
 27 Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h
 28 */
 29 static float z_square(float f){ return (float)f*f; };
 30 static float z_cubic_(float f){ return (float)powf(f, 3); };
 31 
 32 typedef struct z_bezier_factors_s {
 33     float bezier_step;      // must be divisible by 1.0f
 34     float max_width_diff;   // max width diff between two near lines
 35     float max_move_speed;   // 
 36     float max_linewith;     
 37 } z_bezier_factors ;
 38 
 39 int z_point_equals(z_point *p1, z_point *p2) {
 40     return (p1->x==p2->x&&p1->y==p2->y) ? 1 : 0;
 41 }
 42 
 43 z_fpoint_array *z_keep_fpoint_array(z_fpoint_array *a) {
 44     if(a) a->ref++;
 45     return a;
 46 }
 47 
 48 void z_drop_fpoint_array(z_fpoint_array *a) {
 49     if(!a) return;
 50 
 51     if( !(--(a->ref)) ) {
 52         free(a);
 53     }
 54 }
 55 
 56 z_fpoint_arraylist *z_keep_fpoint_arraylist(z_fpoint_arraylist *l) {
 57     if(!l) return NULL;
 58     l->ref++;
 59     return l;
 60 }
 61 
 62 void z_drop_fpoint_arraylist(z_fpoint_arraylist *l) {
 63     if(!l) return;
 64 
 65     if( !(--(l->ref)) ) {
 66         z_fpoint_arraylist_node *c = l->first;
 67         z_fpoint_arraylist_node *n;
 68         while(c) {
 69             z_drop_fpoint_array(c->a);
 70             n = c->n;
 71             free(c);
 72             c = n;
 73         }
 74     } 
 75 }
 76 
 77 static const float defualt_max_width = 5.0f;
 78 static const float default_min_width = 1.0f;
 79 
 80 z_fpoint_array *z_new_fpoint_array(int initsize, float maxwidth, float minwidth) {
 81     if(initsize<=0) return NULL;
 82     z_fpoint_array *a = malloc(sizeof(z_fpoint_array));
 83     a->point = z_malloc_array(initsize, sizeof(z_fpoint));
 84     a->ref = 1;
 85     a->len = 0;
 86 
 87     if(maxwidth<0 || minwidth<0 || maxwidth<minwidth ){
 88         maxwidth = defualt_max_width;
 89         minwidth = default_min_width;
 90     }
 91 
 92     a->maxwidth = maxwidth;
 93     a->minwidth = minwidth;
 94 
 95     a->cap = initsize;
 96     return a;
 97 }
 98 
 99 z_fpoint_array *z_resize_fpoints_array(z_fpoint_array* a, int count){
100     if(!a || count<=0) return NULL;
101 
102     a->point = (z_fpoint*)z_resize_array(a->point, count, sizeof(z_fpoint));
103     a->cap = count;
104     a->len = min(a->cap, a->len);
105     return a;
106 }
107 
108 z_fpoint_arraylist *z_new_fpoint_arraylist() {
109     z_fpoint_arraylist *l = z_malloc_struct(z_fpoint_arraylist);
110     l->ref = 1;
111     l->first = l->end = NULL;
112     return l;
113 }
114 
115 void z_fpoint_arraylist_append(z_fpoint_arraylist *l, z_fpoint_array *a) {
116     z_fpoint_arraylist_node *node = z_malloc_struct(z_fpoint_arraylist_node);
117     node->a = z_keep_fpoint_array(a);
118     node->n = NULL;
119 
120     if(!l->first) {
121         l->first = node;
122     }
123     else {
124         l->end->n = node;
125     }
126 
127     l->end = node;
128 }
129 
130 z_fpoint_array *z_fpoint_arraylist_append_new(z_fpoint_arraylist *l, float max, float min) {
131     z_fpoint_array *a = z_new_fpoint_array(24, max, min);
132     z_fpoint_arraylist_append(l, a);
133     printf("append new points array\n");
134     return a; 
135 }
136 
137 void z_fpoint_arraylist_removelast(z_fpoint_arraylist *l) {
138     
139     z_fpoint_arraylist_node *c = l->first;
140 
141     z_drop_fpoint_array(l->end->a);
142     free(l->end);
143 
144     while(c->n != l->end) { c = c->n; }
145 
146     c->n = NULL;
147     l->end = c; 
148 }
149 
150 z_fpoint_array *z_auto_increase_fpoints_array(z_fpoint_array *a) {
151     int cap = a->cap + (a->cap+3)/4;
152     return z_resize_fpoints_array(a, cap);
153 }
154 
155 float z_movespeed(z_ipoint s, z_ipoint e) {
156     float d = z_distance(s.p, e.p);
157     return (0==d) ? 0 : d/(e.t-s.t);
158 }
159 
160 float z_distance(z_point b, z_point e){
161     return (float)sqrtf( z_square(e.x-b.x) + z_square(e.y-b.y) );
162 }
163 
164 void  z_fpoint_add_xyw(z_fpoint_array *a, float x, float y, float w)  {
165     if( !a || (a->point[a->len-1].p.x==x && a->point[a->len-1].p.y==y) ) return;
166     
167     if(a->len==a->cap) 
168         z_auto_increase_fpoints_array(a);
169 
170     z_fpoint *p = a->point + (a->len++);
171     p->p.x = x; p->p.y = y; p->w = w;
172 }
173 
174 void  z_fpoint_add(z_fpoint_array *a, z_fpoint p) {
175     z_fpoint_add_xyw(a, p.p.x, p.p.y, p.w);
176 }
177 
178 void  z_fpoint_differential_add(z_fpoint_array *a, z_fpoint p) {
179     if(!a) return; 
180 
181     if( a->len==0 ) {
182         z_fpoint_add(a, p);
183         return;
184     }
185 
186 // #define bad_show
187 #ifdef bad_show
188     z_fpoint_add(a, p);
189     return;
190 #endif
191     float max_diff = 0.1f;
192     z_fpoint *last = a->point + (a->len-1);
193     z_point sp = last->p;
194     float sw = last->w;
195     
196     int n = (int)((fabsf(p.w - last->w) / max_diff) + 1);
197     float x_step = (p.p.x - sp.x) / n;
198     float y_step = (p.p.y - sp.y) / n;
199     float w_step = (p.w - sw)      / n;
200     
201     int i;
202     for(i=0; i<(n-1); i++ ){
203         sp.x += x_step;
204         sp.y += y_step;
205         sw += w_step;
206         z_fpoint_add_xyw(a, sp.x, sp.y, sw);
207     }
208     z_fpoint_add(a, p);
209 }
210 
211 void  z_square_bezier(z_fpoint_array *a, z_fpoint b, z_point c, z_fpoint e){
212     if(!a) return;
213     const float f = 0.1f;
214     for(float t=f; t<=1.0; t+=f ) {
215         float x1 = z_square(1-t)*b.p.x + 2*t*(1-t)*c.x + z_square(t)*e.p.x;
216         float y1 = z_square(1-t)*b.p.y + 2*t*(1-t)*c.y + z_square(t)*e.p.y;
217         float w = b.w + (t* (e.w-b.w));
218         z_fpoint pw = { {x1, y1}, w};
219         z_fpoint_differential_add(a, pw);
220     }
221 }
222 
223 float z_linewidth(z_ipoint b, z_ipoint e, float bwidth, float step) {
224     const float max_speed = 2.0f;
225     float d = z_distance(b.p, e.p);
226     float s = d / (e.t - b.t); s = s > max_speed ? max_speed : s;
227     float w = (max_speed-s) / max_speed;
228     float max_dif = d * step;
229     if( w<0.05f ) w = 0.05f;
230     if( fabs( w-bwidth ) > max_dif ) {
231         if( w > bwidth )
232             w = bwidth + max_dif;
233         else
234             w = bwidth - max_dif;
235     }
236     // printf("d:%.4f, time_diff:%lld, speed:%.4f, width:%.4f\n", d, e.t-b.t, s, w);
237     return w;
238 }
239 
240 
241 float z_insert_point(z_fpoint_array *arr, z_point point) {
242 
243     if(!arr) return 0;
244     int len = arr->len;
245 
246     z_point zp = {point.x, point.y};
247     if( 0==len ){
248         z_fpoint p = {zp, 0.4f};
249         z_fpoint_add(arr, p); 
250         z_fpoint_array_set_last_info(arr, point, p.w);
251         return p.w;
252     }
253 
254     int64_t cur_ms = clock();
255     float last_width = arr->last_width;
256     int64_t last_ms = arr->last_ms;
257     z_point last_point = arr->last_point;
258 
259     printf("cur_ms - last_ms = 0x%llx\n", cur_ms - last_ms);
260     // 两次采样时间小于25毫秒, 或者距离小于2个像素, 不采样计算!!!  
261     float distance = z_distance(point, last_point);
262     if( (cur_ms-last_ms) < 50 || distance < 3) {
263         return 0;
264     }
265 
266     float step = arr->len > 4 ? 0.05f : 0.2f;
267     z_ipoint bt = { {last_point.x,last_point.y}, last_ms};
268     z_ipoint et = { zp, cur_ms};
269     float w = (z_linewidth(bt, et, last_width, step) + last_width) / 2;
270     z_fpoint_array *points = z_new_fpoint_array(51, arr->maxwidth, arr->minwidth);
271     z_fpoint tmppoint = arr->point[len-1];
272     z_fpoint_add(points, tmppoint);
273 
274     if( 1==len ) {
275         z_fpoint p = { {(bt.p.x + et.p.x + 1) / 2, (bt.p.y + et.p.y +1) / 2}, w};
276         z_fpoint_differential_add(points, p);
277         w = p.w;
278     }
279     else {
280         z_fpoint bw = tmppoint;
281         z_point c =  {last_point.x,last_point.y};
282         z_fpoint ew = {{(last_point.x + point.x)/2, (last_point.y + point.y)/2}, w};
283         z_square_bezier(points, bw, c, ew);
284     }
285     
286     // escape the first point
287     int i;
288     for(i=1; i<points->len; i++) {
289         z_fpoint_add(arr, points->point[i]);
290     }
291 
292     z_drop_fpoint_array(points); 
293     z_fpoint_array_set_last_info(arr, point, w);
294 
295     return w;
296 }
297 
298 void z_insert_last_point(z_fpoint_array *arr, z_point e) {
299     if(!arr) return;
300     long len= arr->len;
301     if(len==0 ) return;
302     z_fpoint_array *points = z_new_fpoint_array(51, arr->maxwidth, arr->minwidth);
303     z_fpoint zb = arr->point[len-1];
304     z_fpoint_add(points, zb);
305     
306     z_fpoint ze = { {e.x, e.y}, 0.1f};
307     z_fpoint_differential_add(points, ze);
308     int i;
309     for(i=1; i<points->len; i++) {
310         z_fpoint_add(arr, points->point[i]);
311     }
312     z_drop_fpoint_array(points);
313 }
314 
315 z_list *z_list_new(z_list_node_alloc_fun allocfun, z_list_node_drop_fun dropfun)
316 {
317     z_list *l = NULL;
318     l = z_malloc_struct(z_list);
319     l->alloc = allocfun;
320     l->drop = dropfun;
321     l->first = l->last = NULL;
322     return l;
323 }
324 
325 void *z_list_append_new(z_list *zlist) 
326 {
327     z_list_node *node = NULL;
328     void *data = NULL;
329 
330     if(!zlist->alloc || !zlist->drop) 
331         return NULL;
332 
333     node = z_malloc_struct(z_list_node);
334     node->data = zlist->alloc();
335     node->n = NULL;
336     node->p = NULL;
337 
338     if(node) {
339         if(!zlist->first) {
340             zlist->first = zlist->last = node;
341         }
342         else {
343             node->n = NULL;
344             node->p = zlist->last;
345             zlist->last->n = node; 
346             zlist->last = node;
347         } 
348         data = node->data;
349     }
350 
351     return data;
352 }
353 void *z_list_remove_last(z_list *zlist) 
354 {
355     void *data = NULL;
356     z_list_node *tmp = zlist->last;
357     if(zlist->last) {
358         tmp = zlist->last;
359         if(zlist->last==zlist->first){
360             zlist->last = zlist->first = NULL;
361         }
362         else {
363             zlist->last = tmp->p;
364             zlist->last->n = NULL;
365         }
366     }
367 
368     if(tmp) {
369         data = tmp->data; 
370         free(tmp);
371     }
372 
373     return data; 
374 }
375 
376 void z_list_clear(z_list *zlist) 
377 {
378     while (zlist->first)
379         zlist->drop(z_list_remove_last(zlist));
380 }
381 
382 void z_list_free(z_list *zlist) 
383 {
384     z_list_clear(zlist);
385     free(zlist);
386 }
387 
388 /* digest must be 33 char size  */
389 // void
390 // z_text_md5(const char* str, char *digest)
391 // {
392 //     int len = strlen(str);
393 //     unsigned char d[16];
394 //     fz_md5 state;
395 //     fz_md5_init(&state);
396 //     fz_md5_update(&state, (const unsigned char*)str, len);
397 //     fz_md5_final(&state, d);
398 // 
399 //     int i;
400 //     for(i=0; i<(int)sizeof(d); i++) {
401 //         sprintf(digest, "%02x", d[i]);
402 //         digest+=2;
403 //     }
404 //     *digest = '\0';
405 // }
406 
407 void* z_malloc_array(unsigned int count, unsigned int size) { 
408     unsigned int totalsize = count * size;
409     if (totalsize <= 0) return 0;
410 
411     void *buffer = malloc(count * size);
412     if(buffer) memset(buffer, 0, count * size);
413     return buffer;
414 }
415 
416 void* z_resize_array(void *p, size_t count, size_t size) {
417     void *np = 0;
418     size_t total_size = count * size;
419 
420     if (total_size <= 0) 
421         return np; 
422 
423     np = realloc(p, total_size);
424 
425     return np;
426 }
427 
428 void z_fpoint_array_set_last_info(z_fpoint_array *arr, z_point last_point, float last_width) {
429     if (!arr) return;
430     arr->last_point = last_point;
431     arr->last_ms = clock();
432     arr->last_width = last_width; 
433     printf("reset last ms to 0x%llx\n", arr->last_ms);
434 }

 演示程序下载 

开心的时候总是过得那么尽快,
留下的连无尽的唏嘘和感慨, 又至时刻跟情人等称拜拜了!!!

说到底展示同布置在化解这些题目时,留下的手笔:

图片 3

亲手写笔迹这一个多元总算是描写了了.在马上几乎篇原创文章中,
我出过多地方尚未章程了将温馨之想法表达清楚,这恐怕也是成千上万程序员攻城狮的老毛病,
表达能力不怎么样.

设若大家有啊不晓或者自己说得起问题之地方,
可以于留言区留言.我会尽量回答.

下面!!!!!!!!**自不得不重新提起一项大让自己气愤的工作!!!!!!!**

无良商家老板娘拖欠两独月工资了, 
穷得叮当响
,我靠!!!!!!!!现在每日吃8片钱之卵炒饭,
早上点同样客,中午吃一半, 晚上吃一半, 日子真实苦啊..

世家而大家觉得就篇稿子针对性君来赞助,
又愿意打赏一些银两, 请拿起而的无绳电话机, 打开你的微信,
扫一扫下方二维码, 作为一个闹骨气之程序员攻城狮,
我非常愿意受大家之支助…哈哈哈!!!

图片 4

 

相关文章