手写原笔迹输入_原笔迹手写实现平滑和笔锋效果之:笔锋效果(三)[完结篇]

1 /*

2 =====================================================================================3 * Filename: z_math.c4 * Description:5 * Version: 1.06 * Created: 06/23/2016 14:53:437 * Revision: none8 * Compiler: gcc9 * Author: zl(88911562@qq.com),10 * Organization:11 * =====================================================================================12 */

13 #include

14 #include

15 #include

16 #include

17 #include

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 intsize);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, floatlast_width);25

26 /***************************** mac stdlib location:27 Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk/usr/include/stdio.h28 */

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 structz_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 floatmax_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 returna;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) returnNULL;58 l->ref++;59 returnl;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, floatminwidth) {81 if(initsize<=0) returnNULL;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

92 a->maxwidth =maxwidth;93 a->minwidth =minwidth;94

95 a->cap =initsize;96 returna;97 }98

99 z_fpoint_array *z_resize_fpoints_array(z_fpoint_array* a, intcount){100 if(!a || count<=0) returnNULL;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 returna;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 returnl;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, floatmin) {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 returna;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 returnz_resize_fpoints_array(a, cap);153 }154

155 floatz_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 floatz_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, floatw) {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_show188 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 inti;202 for(i=0; i

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, floatstep) {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 returnw;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 returnp.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 inti;288 for(i=1; ilen; 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 returnw;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 inti;309 for(i=1; ilen; 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 returnl;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 returnNULL;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 returndata;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 returndata;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 //void390 //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

406

407 void* z_malloc_array(unsigned int count, unsigned intsize) {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 returnbuffer;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 returnnp;422

423 np = realloc(p, total_size);424

425 returnnp;426 }427

428 void z_fpoint_array_set_last_info(z_fpoint_array *arr, z_point last_point, floatlast_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 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值