Example #1
0
int
transform_distance_polyline_sq(struct coord *c, int count, struct coord *ref, struct coord *lpnt, int *pos)
{
	int i,dist,distn;
	struct coord lp;
	if (count < 2)
		return INT_MAX;
	if (pos)
		*pos=0;
	dist=transform_distance_line_sq(&c[0], &c[1], ref, lpnt);
	for (i=2 ; i < count ; i++) {
		distn=transform_distance_line_sq(&c[i-1], &c[i], ref, &lp);
		if (distn < dist) {
			dist=distn;
			if (lpnt)
				*lpnt=lp;
			if (pos)
				*pos=i-1;
		}
	}
	return dist;
}
Example #2
0
int
transform_douglas_peucker(struct coord *in, int count, int dist_sq, struct coord *out)
{
	int ret=0;
	int i,d,dmax=0, idx=0;
	for (i = 1; i < count-2 ; i++) {
		d=transform_distance_line_sq(&in[0], &in[count-1], &in[i], NULL);
		if (d > dmax) {
			idx=i;
			dmax=d;
		}
	}
	if (dmax > dist_sq) {
		ret=transform_douglas_peucker(in, idx, dist_sq, out)-1;
		ret+=transform_douglas_peucker(in+idx, count-idx, dist_sq, out+ret);
	} else {
		if (count > 0)
			out[ret++]=in[0];
		if (count > 1)
			out[ret++]=in[count-1];
	}
	return ret;
}
Example #3
0
int
tracking_update(struct tracking *tr, struct coord *c, int angle)
{
	struct tracking_line *t;
	int i,value,min=0;
	struct coord lpnt;
#if 0
	int min,dist;
	int debug=0;
#endif
	dbg(1,"enter(%p,%p,%d)\n", tr, c, angle);
	dbg(1,"c=0x%x,0x%x\n", c->x, c->y);

	if (c->x == tr->last_in.x && c->y == tr->last_in.y) {
		*c=tr->last_out;
		return 0;
	}
	tr->last_in=*c;
	if (!tr->lines || transform_distance_sq(&tr->last_updated, c) > 250000) {
		dbg(1, "update\n");
		tracking_free_lines(tr);
		tracking_doupdate_lines(tr, c);
		tr->last_updated=*c;
		dbg(1,"update end\n");
	}
		
	t=tr->lines;
	if (! t)
		return 0;
	tr->curr_line=NULL;
	while (t) {
		struct street_data *sd=t->street;
		int dir = 0;
		switch(sd->flags & AF_ONEWAYMASK) {
		case 0:
			dir=0;
			break;
		case 1:
			dir=1;
			break;
		case 2:
			dir=-1;
			break;
		case 3:
			t=t->next;
			continue;
		}
		for (i = 0; i < sd->count-1 ; i++) {
			dbg(2, "%d: (0x%x,0x%x)-(0x%x,0x%x)\n", i, sd->c[i].x, sd->c[i].y, sd->c[i+1].x, sd->c[i+1].y);
			value=transform_distance_line_sq(&sd->c[i], &sd->c[i+1], c, &lpnt);
			if (value < INT_MAX/2) 
				value += tracking_angle_delta(angle, t->angle[i], dir)*angle_factor;
			if (tracking_is_connected(tr->curr, &sd->c[i]))
				value += connected_pref;
			if (lpnt.x == tr->last_out.x && lpnt.y == tr->last_out.y)
				value += nostop_pref;
			if (! tr->curr_line || value < min) {
				tr->curr_line=t;
				tr->pos=i;
				tr->curr[0]=sd->c[i];
				tr->curr[1]=sd->c[i+1];
				dbg(1,"lpnt.x=0x%x,lpnt.y=0x%x pos=%d %d+%d+%d+%d=%d\n", lpnt.x, lpnt.y, i, 
					transform_distance_line_sq(&sd->c[i], &sd->c[i+1], c, &lpnt),
					tracking_angle_delta(angle, t->angle[i], 0)*angle_factor,
					tracking_is_connected(tr->curr, &sd->c[i]) ? connected_pref : 0,
					lpnt.x == tr->last_out.x && lpnt.y == tr->last_out.y ? nostop_pref : 0,
					value
				);
				tr->last_out=lpnt;
				min=value;
			}
		}
		t=t->next;
	}
	dbg(1,"tr->curr_line=%p\n", tr->curr_line);
	if (!tr->curr_line)
		return 0;
	dbg(1,"found 0x%x,0x%x\n", tr->last_out.x, tr->last_out.y);
	*c=tr->last_out;
	return 1;	
}