⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 abstract_character.cpp

📁 matlab一些常用的处理模块
💻 CPP
📖 第 1 页 / 共 3 页
字号:
 * 获得字符真实高度 * 参数:c        字符 *       angle    角度 * 返回:高度******************************************************************************/float abstract_character::get_real_height(const character &c, float angle){	transformation T(angle, 1, (c.min_x+c.max_x)/2.0, -c.max_y);	for(list<singular_point>::const_iterator i=c.spl.begin(); i!=c.spl.end(); ++i)	{		float x,y;		for(list<inner_sequence_start>::const_iterator j=i->sequences.begin(); j!=i->sequences.end(); ++j)		{			if( j->is_start )			{				for(list<skeleton_sequence>::const_iterator k=j->connect->sseql.begin(); k!=j->connect->sseql.end(); ++k)					stroke(T,					       c.line_thickness,					       k->first->aligned_x,					       k->first->aligned_y,					       k->last->aligned_x,					       k->last->aligned_y);				if( !j->connect->sseql.empty() )				{					stroke(T,					       c.line_thickness,					       i->x,					       i->y,					       j->connect->sseql.front().first->aligned_x,					       j->connect->sseql.front().first->aligned_x);										stroke(T,					       c.line_thickness,					       j->connect->sseql.back().last->aligned_x,					       j->connect->sseql.back().last->aligned_y,					       j->connect->point2->x,					       j->connect->point2->y);				}			}		}		T.transform(i->x,i->y,x,y);	}	return T.transformed_height();}/****************************************************************************** * 构造函数******************************************************************************/abstract_character::abstract_character(const character &c, float base_line_pos, float reference_height, float angle){	if( base_line_pos==FLT_MAX )		base_line_pos=-c.max_y;	else		base_line_pos=-c.max_y-base_line_pos;	if( reference_height==0 )		reference_height=c.max_y-c.min_y+1;	// 确保size总是>=1	transformation T(angle, 1/reference_height, (c.min_x+c.max_x)/2.0, base_line_pos);	hash_map<const singular_point*, int, hash<const singular_point*> > spmap;	hash_map<const connection*, int, hash<const connection*> > conmap;	// 预申请内存	int num_sp=0;	int num_con=0;	for(list<singular_point>::const_iterator i=c.spl.begin(); i!=c.spl.end(); ++i)	{		num_sp++;		for(list< inner_sequence_start >::const_iterator j=i->sequences.begin(); j!=i->sequences.end(); ++j)			if( j->is_start )				num_con++;	}	aspv.reserve(num_sp);	acv.reserve(num_con);	for(list<singular_point>::const_iterator i=c.spl.begin(); i!=c.spl.end(); ++i)		resolve_sp(&(*i),spmap,conmap,T);	// 旋转后纠正x坐标	float center_x=(T.minx()+T.maxx())/2;	for(vector<abstract_singular_point>::iterator i=aspv.begin(); i!=aspv.end(); ++i)		i->x-=center_x;	for(vector<abstract_connection>::iterator i=acv.begin(); i!=acv.end(); ++i)		for(list< point<float> >::iterator j=i->polyline.begin(); j!=i->polyline.end(); ++j)			j->x-=center_x;}/****************************************************************************** * 写文件******************************************************************************/void abstract_character::write(fstream &fs) const{	ostream	&o=fs;	for(vector<abstract_singular_point>::const_iterator i=aspv.begin(); i!=aspv.end(); ++i)	{		o << i->x << ' ' << i->y << ' ' << i->type;		for(list<int>::const_iterator j=i->acl.begin(); j!=i->acl.end(); ++j)			o << ' ' << *j;		o << '\n';	}	o << "CON\n";	for(vector<abstract_connection>::const_iterator i=acv.begin(); i!=acv.end(); ++i)	{		o << i->singular_point_1 << ' ' << i->singular_point_2 << ' ' << i->type;		for(list< point<float> >::const_iterator j=i->polyline.begin(); j!=i->polyline.end(); ++j)			o << ' ' << j->x << ',' << j->y;		o << '\n';	}	o << '\n';}/****************************************************************************** * 读文件******************************************************************************/void abstract_character::read(fstream &fs){	int max_sp=-1, max_con=-1;	istream	&is=fs;	aspv.clear();	acv.clear();	string s;	char *endptr;	while( (s=get_next_token(is))!="" )	{		if( s=="CON" )			break;		aspv.push_back( abstract_singular_point() );		abstract_singular_point &asp=aspv.back();		asp.x=strtod(s.c_str(),&endptr);		asp.y=get_next_float(is);		s=get_next_token(is);		if( s=="end_point" )			asp.type=end_point;		else if( s=="branching_point" )			asp.type=branching_point;		else			asp.type=turning_point;		while( (s=get_next_token(is))!="" && s!="\n" )			asp.acl.push_back( my_max(strtol(s.c_str(),&endptr,10),max_con) );	}	get_next_token(is);	// nl	while( (s=get_next_token(is))!="" && s!="\n" )	{		acv.push_back( abstract_connection() );		abstract_connection &ac=acv.back();		ac.singular_point_1=my_max(strtol(s.c_str(),&endptr,10),max_sp);		ac.singular_point_2=my_max(get_next_int(is),max_sp);		s=get_next_token(is);		if( s=="straight" )			ac.type=straight;		else if( s=="left_curved" )			ac.type=left_curved;		else			ac.type=right_curved;		while( is.peek()!=EOF && static_cast<char>(is.peek())!='\n' )		{			float x=get_next_float(is);			get_next_token(is);			float y=get_next_float(is);			ac.polyline.push_back( point<float>(x,y) );		}		get_next_token(is);	}	assert( max_sp < static_cast<int>(aspv.size()) && max_con < static_cast<int>(acv.size()) );}/****************************************************************************** * 增加连接******************************************************************************/void abstract_singular_point::add_connection(int cnr){	// 确保元素唯一	for(list<int>::iterator i=acl.begin(); i!=acl.end(); ++i)		if( *i==cnr )			return;	acl.push_back(cnr);}/****************************************************************************** * 重置匹配状态******************************************************************************/void abstract_character::reset_matching_state(){	for(vector<abstract_connection>::iterator i=acv.begin(); i!=acv.end(); ++i)		i->reset_matching_state();}/****************************************************************************** * line类******************************************************************************/struct line : public straight_line{	line(const point<float> &start_point, const point<float> &end_point) :		straight_line(start_point.x,start_point.y,end_point.x,end_point.y), start(start_point), end(end_point) {}	bool is_on_line(point<float> p) const;	bool intersect_line(const line &l, point<float> &p, bool &have_straight_intersection) const;	bool intersect_line(const line &l, point<float> &p) const;	point<float> start;	point<float> end;};/****************************************************************************** * 判断一个点是否在线上 * 参数:p   点 * 返回:在线上,返回true;否则返回false******************************************************************************/bool line::is_on_line(point<float> p) const{	return is_part_of(start.x,start.y, end.x,end.y, p.x,p.y);}/****************************************************************************** * 交叉线******************************************************************************/bool line::intersect_line(const line &l, point<float> &p) const{	return intersect(l,p.x,p.y) && is_on_line(p) && l.is_on_line(p);}/****************************************************************************** * 交叉线******************************************************************************/bool line::intersect_line(const line &l, point<float> &p, bool &have_straight_intersection) const{	return (have_straight_intersection=intersect(l,p.x,p.y)) && is_on_line(p) && l.is_on_line(p);}/****************************************************************************** * check_point结构******************************************************************************/struct check_point{	typedef enum {db_end_point, other_end_point, intersection_point}	check_point_type;	check_point_type	type;		// check_point的类型	point<float>		db_cpoint;	// 参考线上的点	point<float>		other_cpoint;	// 直线上另一边的对应点	line*			db_line;	line*			other_line;	bool			is_valid;	bool			source_is_db;	bool			is_start;	float			coefficient;	check_point() {}	check_point(line& db, line& other, bool isdb, bool isstart);	check_point(const point<float> p, line& rl, line& other) :		type(intersection_point), db_cpoint(p), other_cpoint(p), db_line(&rl), other_line(&other), is_valid(true) { set_line_coefficient(); coefficient+=10*FLT_EPSILON; }	void set_line_coefficient();	float line_coefficient() const { return coefficient; }	bool operator<(const check_point& c) const { return line_coefficient()<c.line_coefficient(); }};/****************************************************************************** * 构造函数******************************************************************************/check_point::check_point(line& db, line& other, bool isdb, bool isstart) :	db_line(&db), other_line(&other), source_is_db(isdb), is_start(isstart){	if( source_is_db )	{		type=db_end_point;		db_cpoint=is_start ? db_line->start : db_line->end;		is_valid=other_line->intersect(db_line->normal(db_cpoint.x,db_cpoint.y),other_cpoint.x,other_cpoint.y) &&			 other_line->is_on_line(other_cpoint);	}	else	{		type=other_end_point;		other_cpoint=is_start ? other_line->start : other_line->end;		db_line->construct_perpendicular(other_cpoint.x,other_cpoint.y,db_cpoint.x,db_cpoint.y);		is_valid=db_line->is_on_line(db_cpoint);	}	set_line_coefficient();}/****************************************************************************** * 设置line的相关系数******************************************************************************/void check_point::set_line_coefficient(){	// 参考向量	const float v1 = db_line->end.x-db_line->start.x;	const float v2 = db_line->end.y-db_line->start.y;	// 测试向量	const float w1 = db_cpoint.x-db_line->start.x;	const float w2 = db_cpoint.y-db_line->start.y;		// 卷积	coefficient = v1*w1+v2*w2;}bool path::match_connection(const path &other_path, float &divergence, match_debug_info *mdi) const{	#ifdef DEBUG_MATCHING		if( mdi )		{			cout << "--- match_connection ---" << endl;			cout << "database path: " << *this << endl;			cout << "real path    : " << other_path << endl;		}	#endif	float total_area=0;	match_debug_info curr_mdi;	// 数据库端	const_iterator	db_iter=begin();	const_iterator	db_end=end();	line		db_line(*db_iter, *(++db_iter));	line		new_db_line=db_line;	// 其它端	const_iterator	other_iter=other_path.begin();	const_iterator	other_end=other_path.end();	line		other_line(*other_iter, *(++other_iter));	line		new_other_line=other_line;	bool run_loop=true;	float weight; 	do {		weight=other_iter.get_weight();		slist<check_point>	cpl;		for(int i=0; i<4; i++)			cpl.insert_sorted( check_point(db_line,other_line,i<2,i%2) );		bool have_intersection, have_line_intersection;		point<float> p_intersect;		if( (have_line_intersection=db_line.intersect_line(other_line,p_intersect,have_intersection)) )			cpl.insert_sorted( check_point(p_intersect,db_line,other_line) );		point<float>*	other_line_lower_start=NULL;		slist<check_point>::iterator i=cpl.begin();		while(			!is_equal(euklidian_distance(new_db_line.start.x,new_db_line.start.y, new_db_line.end.x,new_db_line.end.y),0) &&			!is_equal(euklidian_distance(new_other_line.start.x,new_other_line.start.y, new_other_line.end.x,new_other_line.end.y),0)		     )		{			check_point &first=*i;			check_point &second=*(++i);						if( !other_line_lower_start && first.type==check_point::other_end_point )				other_line_lower_start=first.is_start?&new_other_line.start:&new_other_line.end;			if( !other_line_lower_start && second.type==check_point::other_end_point )				other_line_lower_start=second.is_start?&new_other_line.start:&new_other_line.end;						if( first.is_valid )	// 计算包围域			{				float tmp_area=fabs(0.5 *((first.db_cpoint.x-first.other_cpoint.x) * (first.db_cpoint.y+first.other_cpoint.y)+						          (first.other_cpoint.x-second.other_cpoint.x) * (first.other_cpoint.y+second.other_cpoint.y)+						          (second.other_cpoint.x-second.db_cpoint.x) * (second.other_cpoint.y+second.db_cpoint.y)+						          (second.db_cpoint.x-first.db_cpoint.x) * (second.db_cpoint.y+first.db_cpoint.y)));				int color=0;				if( have_intersection )				{					float angle=fabs(angle_between(db_line.start.x,db_line.start.y, p_intersect.x,p_intersect.y, other_line.start.x,other_line.start.y));					if( angle>M_PI_2 )						angle=M_PI-angle;					float tmp_area2=euklidian_distance(first.other_cpoint.x,first.other_cpoint.y, second.other_cpoint.x,second.other_cpoint.y);					tmp_area2=angle/M_PI_2*tmp_area2*tmp_area2;					if( tmp_area2>tmp_area )					{						tmp_area=tmp_area2;						color=1;					}				}				if ( mdi )					curr_mdi.add_square(first.db_cpoint,first.other_cpoint,second.other_cpoint,second.db_cpoint,color);				total_area+=weight*tmp_area;								// 通过匹配线削短余下的线				new_db_line.start=second.db_cpoint;				*other_line_lower_start=second.other_cpoint;			}			else			// 未匹配的线段			{				float segment_area;				if( first.source_is_db )				{					if( mdi )

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -