亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? stroke.c

?? Linux環(huán)境下手寫輸入程序。手寫輸入
?? C
字號:
/*cellwriter -- a character recognition input methodCopyright (C) 2007 Michael Levin <risujin@risujin.org>This program is free software; you can redistribute it and/ormodify it under the terms of the GNU General Public Licenseas published by the Free Software Foundation; either version 2of the License, or (at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program; if not, write to the Free SoftwareFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.*/#include "config.h"#include <string.h>#include <math.h>#include <gtk/gtk.h>#include "common.h"#include "recognize.h"/*        Stroke functions*//* Distance from the line formed by the two neighbors of a point, which, if   not exceeded, will cause the point to be culled during simplification */#define SIMPLIFY_THRESHOLD 0.5/* Granularity of stroke point array in points */#define POINTS_GRAN 64/* Size of a stroke structure */#define STROKE_SIZE(size) (sizeof (Stroke) + (size) * sizeof (Point))void process_stroke(Stroke *stroke)/* Generate cached parameters of a stroke */{        int i;        float distance;        if (stroke->processed)                return;        stroke->processed = TRUE;        /* Dot strokes */        if (stroke->len == 1) {                vec2_set(&stroke->center, stroke->points[0].x,                         stroke->points[0].y);                stroke->spread = 0.f;                return;        }        stroke->min_x = stroke->max_x = stroke->points[0].x;        stroke->min_y = stroke->max_y = stroke->points[0].y;        for (i = 0, distance = 0.; i < stroke->len - 1; i++) {                Vec2 v;                float weight;                /* Angle */                vec2_set(&v, stroke->points[i + 1].x - stroke->points[i].x,                         stroke->points[i + 1].y - stroke->points[i].y);                stroke->points[i].angle = vec2_angle(&v);                /* Point contribution to spread */                if (stroke->points[i + 1].x < stroke->min_x)                        stroke->min_x = stroke->points[i + 1].x;                if (stroke->points[i + 1].y < stroke->min_y)                        stroke->min_y = stroke->points[i + 1].y;                if (stroke->points[i + 1].x > stroke->max_x)                        stroke->max_x = stroke->points[i + 1].x;                if (stroke->points[i + 1].y > stroke->max_y)                        stroke->max_y = stroke->points[i + 1].y;                /* Segment contribution to center */                vec2_set(&v, stroke->points[i + 1].x - stroke->points[i].x,                         stroke->points[i + 1].y - stroke->points[i].y);                distance += weight = vec2_mag(&v);                vec2_set(&v, stroke->points[i + 1].x + stroke->points[i].x,                         stroke->points[i + 1].y + stroke->points[i].y);                vec2_scale(&v, &v, weight / 2.);                vec2_sum(&stroke->center, &stroke->center, &v);        }        vec2_scale(&stroke->center, &stroke->center, 1. / distance);        stroke->points[i].angle = stroke->points[i - 1].angle;        stroke->distance = distance;        /* Stroke spread */        stroke->spread = stroke->max_x - stroke->min_x;        if (stroke->max_y - stroke->min_y > stroke->spread)                stroke->spread = stroke->max_y - stroke->min_y;}void clear_stroke(Stroke *stroke)/* Clear cached parameters */{        int size;        size = stroke->size;        memset(stroke, 0, sizeof (*stroke));        stroke->size = size;}Stroke *stroke_new(int size)/* Allocate memory for a new stroke */{        Stroke *stroke;        if (size < POINTS_GRAN)                size = POINTS_GRAN;        stroke = g_malloc(STROKE_SIZE(size));        stroke->size = size;        clear_stroke(stroke);        return stroke;}static void reverse_copy_points(Point *dest, const Point *src, int len){        int i;        for (i = 0; i < len; i++) {                ANGLE angle = 0;                if (i < len - 1)                        angle = src[len - i - 2].angle + ANGLE_PI;                dest[i] = src[len - i - 1];                dest[i].angle = angle;        }}Stroke *stroke_clone(const Stroke *src, int reverse){        Stroke *stroke;        if (!src)                return NULL;        stroke = stroke_new(src->size);        if (!reverse)                memcpy(stroke, src, STROKE_SIZE(src->size));        else {                memcpy(stroke, src, sizeof (Stroke));                reverse_copy_points(stroke->points, src->points, src->len);        }        return stroke;}void stroke_free(Stroke *stroke){        g_free(stroke);}void glue_stroke(Stroke **pa, const Stroke *b, int reverse)/* Glue B onto the end of A preserving processed properties */{        Vec2 glue_seg, glue_center, b_center;        Point start;        Stroke *a;        float glue_mag;        a = *pa;        /* If there is no stroke to glue to, just copy */        if (!a || a->len < 1) {                if (a->len < 1)                        stroke_free(a);                *pa = stroke_clone(b, reverse);                return;        }        /* Allocate memory */        if (a->size < a->len + b->len) {                a->size = a->len + b->len;                a = g_realloc(a, STROKE_SIZE(a->size));        }        /* Gluing two strokes creates a new segment between them */        start = reverse ? b->points[b->len - 1] : b->points[0];        vec2_set(&glue_seg, start.x - a->points[a->len - 1].x,                 start.y - a->points[a->len - 1].y);        vec2_set(&glue_center, (start.x + a->points[a->len - 1].x) / 2,                 (start.y + a->points[a->len - 1].y) / 2);        glue_mag = vec2_mag(&glue_seg);        /* Compute new spread */        if (b->min_x < a->min_x)                a->min_x = b->min_x;        if (b->max_x > a->max_x)                a->max_x = b->max_x;        if (b->min_y < a->min_y)                a->min_y = b->min_y;        if (b->max_y > a->max_y)                a->max_y = b->max_y;        a->spread = a->max_x - a->min_x;        if (a->max_y - a->min_y > a->spread)                a->spread = a->max_y - a->min_y;        /* Compute new center point */        vec2_scale(&a->center, &a->center, a->distance);        vec2_scale(&b_center, &b->center, b->distance);        vec2_scale(&glue_center, &glue_center, glue_mag);        vec2_set(&a->center, a->center.x + b_center.x + glue_center.x,                 a->center.y + b_center.y + glue_center.y);        vec2_scale(&a->center, &a->center,                   1.f / (a->distance + b->distance + glue_mag));        /* Copy points */        if (!reverse || b->len < 2)                memcpy(a->points + a->len, b->points, b->len * sizeof (Point));        else                reverse_copy_points(a->points + a->len, b->points, b->len);        a->points[a->len - 1].angle = vec2_angle(&glue_seg);        a->distance += glue_mag + b->distance;        a->len += b->len;        *pa = a;}void draw_stroke(Stroke **ps, int x, int y)/* Add a point in scaled coordinates to a stroke */{        /* Create a new stroke if necessary */        if (!(*ps))                *ps = stroke_new(0);        /* If we run out of room, resample the stroke to fit */        if ((*ps)->len >= POINTS_MAX) {                Stroke *new_stroke;                new_stroke = sample_stroke(NULL, *ps, POINTS_MAX - POINTS_GRAN,                                           POINTS_MAX);                stroke_free(*ps);                *ps = new_stroke;        }        /* Range limits */        if (x <= -SCALE / 2)                x = -SCALE / 2 + 1;        if (x >= SCALE / 2)                x = SCALE / 2 - 1;        if (y <= -SCALE / 2)                y = -SCALE / 2 + 1;        if (y >= SCALE / 2)                y = SCALE / 2 - 1;        /* Do we need more memory? */        if ((*ps)->len >= (*ps)->size) {                (*ps)->size += POINTS_GRAN;                *ps = g_realloc(*ps, STROKE_SIZE((*ps)->size));        }        (*ps)->points[(*ps)->len].x = x;        (*ps)->points[(*ps)->len++].y = y;}void smooth_stroke(Stroke *s)/* Smooth stroke points by moving each point halfway toward the line between   its two neighbors */{        int i, last_x, last_y;        last_x = s->points[0].x;        last_y = s->points[0].y;        for (i = 1; i < s->len - 1; i++) {                Vec2 a, b, c, m, ab, ac, am;                if (last_x == s->points[i + 1].x &&                    last_y == s->points[i + 1].y) {                        last_x = s->points[i].x;                        last_y = s->points[i].y;                        continue;                }                vec2_set(&a, last_x, last_y);                vec2_set(&b, s->points[i].x, s->points[i].y);                vec2_set(&c, s->points[i + 1].x, s->points[i + 1].y);                vec2_sub(&ac, &c, &a);                vec2_sub(&ab, &b, &a);                vec2_proj(&am, &ab, &ac);                vec2_sum(&m, &a, &am);                vec2_avg(&b, &b, &m, 0.5);                last_x = s->points[i].x;                last_y = s->points[i].y;                s->points[i].x = b.x + 0.5;                s->points[i].y = b.y + 0.5;        }}void simplify_stroke(Stroke *s)/* Remove excess points between neighbors */{	int i;	for (i = 1; i < s->len - 1; i++) {	        Vec2 l, w;		double dist, mag, dot;                /* Vector l is a unit vector from point i - 1 to point i + 1 */		vec2_set(&l, s->points[i - 1].x - s->points[i + 1].x,		         s->points[i - 1].y - s->points[i + 1].y);		mag = vec2_norm(&l, &l);		/* Vector w is a vector from point i - 1 to point i */		vec2_set(&w, s->points[i - 1].x - s->points[i].x,		         s->points[i - 1].y - s->points[i].y);		/* Do not touch mid points that are not in between their		   neighbors */		dot = vec2_dot(&l, &w);		if (dot < 0. || dot > mag)		        continue;		/* Remove any points that are less than some threshold away		   from their neighbor points */		dist = vec2_cross(&w, &l);		if (dist < SIMPLIFY_THRESHOLD && dist > -SIMPLIFY_THRESHOLD) {			memmove(s->points + i, s->points + i + 1,			        (--s->len - i) * sizeof (*s->points));			i--;		}	}}void dump_stroke(Stroke *stroke){        int i;        /* Print stats */        g_message("Stroke data --");        g_debug("Distance: %g", stroke->distance);        g_debug("  Center: (%g, %g)", stroke->center.x, stroke->center.y);        g_debug("  Spread: %d", stroke->spread);        g_message("%d points --", stroke->len);        /* Print point data */        for (i = 0; i < stroke->len; i++)                g_debug("%3d: (%4d,%4d)\n",                        i, stroke->points[i].x, stroke->points[i].y);}Stroke *sample_stroke(Stroke *out, Stroke *in, int points, int size)/* Recreate the stroke by sampling at regular distance intervals.   Sampled strokes always have angle data. */{        Vec2 v;        double dist_i, dist_j, dist_per;        int i, j, len;        if (!in || in->len < 1) {                g_warning("Attempted to sample an invalid stroke");                return NULL;        }        /* Check ranges */        if (size >= POINTS_MAX) {                g_warning("Stroke sized to maximum length possible");                size = POINTS_MAX;        }        if (points >= POINTS_MAX) {                g_warning("Stroke sampled to maximum length possible");                points = POINTS_MAX;        }        if (size < 1)                size = 1;        if (points < 1)                points = 1;        /* Allocate memory and copy cached data */        if (!out)                out = g_malloc(STROKE_SIZE(size));        out->size = size;        len = out->size < points ? out->size - 1 : points - 1;        out->len = len + 1;        out->spread = in->spread;        out->center = in->center;        /* Special case for sampling a single point */        if (in->len <= 1 || points <= 1) {                for (i = 0; i < len + 1; i++)                        out->points[i] = in->points[0];                out->distance = 0.;                return out;        }        dist_per = in->distance / (points - 1);        out->distance = in->distance;        vec2_set(&v, in->points[1].x - in->points[0].x,                 in->points[1].y - in->points[0].y);        dist_j = vec2_mag(&v);        dist_i = dist_per;        out->points[0] = in->points[0];        for (i = 1, j = 0; i < len; i++) {                /* Advance our position */                while (dist_i >= dist_j) {                        if (j >= in->len - 2)                                goto finish;                        dist_i -= dist_j;                        j++;                        vec2_set(&v, in->points[j + 1].x - in->points[j].x,                                 in->points[j + 1].y - in->points[j].y);                        dist_j = vec2_mag(&v);                }                /* Interpolate points */                out->points[i].x = in->points[j].x +                                   (in->points[j + 1].x - in->points[j].x) *                                   dist_i / dist_j;                out->points[i].y = in->points[j].y +                                   (in->points[j + 1].y - in->points[j].y) *                                   dist_i / dist_j;                out->points[i].angle = in->points[j].angle;                dist_i += dist_per;        }finish:        for (; i < len + 1; i++)                out->points[i] = in->points[j + 1];        return out;}void sample_strokes(Stroke *a, Stroke *b, Stroke **as, Stroke **bs)/* Sample multiple strokes to equal lengths */{        double dist;        int points;        /* Find the sample length */        dist = a->distance;        if (b->distance > dist)                dist = b->distance;        points = 1 + dist / FINE_RESOLUTION;        if (points > POINTS_MAX)                points = POINTS_MAX;        *as = sample_stroke(NULL, a, points, points);        *bs = sample_stroke(NULL, b, points, points);}

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人性生交大片免费看中文网站| 播五月开心婷婷综合| 麻豆精品国产传媒mv男同| 国产精品影视天天线| 欧美日韩中字一区| 久久女同精品一区二区| 亚洲欧美一区二区三区久本道91| 日韩精品成人一区二区三区| 成人免费视频视频| 69精品人人人人| 欧美性受xxxx| 久久久精品中文字幕麻豆发布| 性做久久久久久| 成人黄色综合网站| 精品奇米国产一区二区三区| 国产欧美一区二区精品性色超碰| 日本美女一区二区三区视频| 成人一区二区三区| 日韩午夜av一区| 丝袜a∨在线一区二区三区不卡| 成人国产精品免费观看动漫| 亚洲国产精品成人久久综合一区| 欧美激情中文字幕| 青青草原综合久久大伊人精品 | 国产精品萝li| 蜜臀av一区二区三区| 99久久99久久久精品齐齐| 国产亚洲一区字幕| 日韩电影在线免费观看| 色综合久久久久久久久| 日韩午夜中文字幕| 午夜精品爽啪视频| 色吊一区二区三区| 亚洲视频精选在线| 91久久一区二区| 国产精品成人一区二区三区夜夜夜| 亚洲成年人影院| 欧美一区二区视频观看视频| 亚洲综合视频网| 99久久99久久精品免费观看| 国产欧美一区二区精品性| 成人三级伦理片| 久久精品一区二区三区av| 激情五月激情综合网| 久久伊人蜜桃av一区二区| 精品影院一区二区久久久| 日韩美一区二区三区| 国产精品77777竹菊影视小说| 精品成人一区二区三区| 精品伊人久久久久7777人| 国产婷婷一区二区| 国产乱子轮精品视频| 精品美女一区二区| 国产欧美日本一区二区三区| 成人教育av在线| 中文字幕亚洲不卡| 99久久亚洲一区二区三区青草 | 高清久久久久久| 国产精品欧美一区喷水| 不卡视频一二三| 一区二区三区资源| 欧美在线观看一区| 日韩国产精品91| 欧美日本在线观看| 美国毛片一区二区| 久久先锋影音av| 激情欧美日韩一区二区| 亚洲国产精品ⅴa在线观看| 成+人+亚洲+综合天堂| 欧美日韩电影在线播放| 国内精品伊人久久久久av一坑| 国产欧美日韩在线看| 色悠久久久久综合欧美99| 久久精品久久99精品久久| 国产欧美一区二区三区在线看蜜臀 | 亚洲国产高清在线观看视频| 成人综合在线网站| 久久久久国产免费免费| 欧美视频日韩视频在线观看| 蜜臀精品一区二区三区在线观看| 欧美va在线播放| 91福利在线播放| 精品一区二区三区的国产在线播放| 国产亚洲精品精华液| 国产盗摄精品一区二区三区在线| 一区二区三区中文免费| 日韩欧美国产麻豆| 美女国产一区二区| 国产精品毛片无遮挡高清| 日韩三级精品电影久久久| 97国产一区二区| 精油按摩中文字幕久久| 一区二区三区av电影| 久久久久久综合| 欧美色区777第一页| 久久精品国产99| 五月婷婷综合在线| 欧美高清在线视频| 欧美一级片在线看| 欧美性猛片xxxx免费看久爱| 国产福利一区在线| 日韩av电影免费观看高清完整版| 欧美一区二区三区在| 色屁屁一区二区| 国产成人综合在线| 蜜桃一区二区三区在线观看| 视频在线观看国产精品| 国产精品久久午夜| 久久日一线二线三线suv| 欧美成人福利视频| 欧美伦理影视网| 91免费视频网| 激情六月婷婷综合| 精品一区免费av| 麻豆精品一区二区三区| 夜夜精品浪潮av一区二区三区| 亚洲视频免费看| 国产精品女同互慰在线看| 精品成人免费观看| 这里只有精品99re| 欧美色爱综合网| 欧美亚洲国产怡红院影院| 国产美女视频91| 成人黄色大片在线观看| 国产电影一区二区三区| 国产在线精品一区二区夜色| 国内精品视频一区二区三区八戒| 亚洲国产精品嫩草影院| 亚洲一区在线免费观看| 国产精品九色蝌蚪自拍| 亚洲欧洲中文日韩久久av乱码| 中文字幕第一区| 国产精品日产欧美久久久久| 欧美极品xxx| 国产精品久久久久久一区二区三区| 久久先锋资源网| 国产拍揄自揄精品视频麻豆| 国产精品私人自拍| 国产精品九色蝌蚪自拍| 亚洲欧洲一区二区在线播放| 亚洲成人精品在线观看| 亚洲国产成人91porn| 亚洲国产精品久久久久秋霞影院| 全部av―极品视觉盛宴亚洲| 日本不卡视频在线| 久久成人免费日本黄色| 国产成人在线视频网站| 99久久99久久综合| 91高清视频在线| 欧美电视剧在线观看完整版| 精品国产91亚洲一区二区三区婷婷| 欧美精品一区二区三区在线播放 | 精品少妇一区二区| 日韩免费视频一区二区| 欧美一区二区播放| 国产精品久久久久7777按摩| 亚洲视频在线一区观看| 亚洲国产精品麻豆| 日韩国产精品91| 中文字幕av资源一区| 国产欧美一区视频| 亚洲电影一区二区| 国内成人精品2018免费看| 成人午夜在线免费| 欧美精品日韩一本| 亚洲国产精品黑人久久久| 婷婷激情综合网| 成人激情小说网站| 日韩欧美国产午夜精品| 洋洋av久久久久久久一区| 国产一区二三区好的| 欧美日韩国产色站一区二区三区| 久久婷婷色综合| 青娱乐精品视频| 欧美性生活影院| 亚洲人成网站在线| 国产酒店精品激情| 精品国产一区二区三区不卡| 亚洲国产精品久久艾草纯爱| 91麻豆swag| 国产精品视频第一区| 韩国女主播一区| 日韩欧美一二三| 日韩av成人高清| 欧美三级视频在线观看| √…a在线天堂一区| 国产乱子伦一区二区三区国色天香| 欧美高清性hdvideosex| 亚洲手机成人高清视频| 国产成人在线观看免费网站| 欧美精品一区二区三区蜜桃视频| 日日骚欧美日韩| 欧美人与z0zoxxxx视频| 亚洲一区二区三区四区不卡| 99这里都是精品| 国产精品乱码一区二区三区软件 | 美女在线一区二区| 欧美日韩成人在线一区| 亚洲第一狼人社区| 欧美年轻男男videosbes|