static real compound_distance_from (Compound * comp, Point * point) { real dist = 0.0; gint num_handles = comp->object.num_handles; Point * mount_point_pos = &comp->mount_point.pos; gint i; dist = distance_line_point (mount_point_pos, &comp->handles[1].pos, comp->line_width, point); if (dist < 0.000001) return 0.0; for (i = 2; i < num_handles; i++) { dist = MIN(distance_line_point (mount_point_pos, &comp->handles[i].pos, comp->line_width, point), dist); if (dist < 0.000001) return 0.0; } return dist; }
static ConnPointLine * other_get_clicked_border(Other *other, Point *clicked) { ConnPointLine *cpl; real dist,dist2; cpl = other->north; dist = distance_line_point(&other->north->start,&other->north->end,0,clicked); dist2 = distance_line_point(&other->west->start,&other->west->end,0,clicked); if (dist2 < dist) { cpl = other->west; dist = dist2; } dist2 = distance_line_point(&other->south->start,&other->south->end,0,clicked); if (dist2 < dist) { cpl = other->south; dist = dist2; } dist2 = distance_line_point(&other->east->start,&other->east->end,0,clicked); if (dist2 < dist) { cpl = other->east; /*dist = dist2;*/ } return cpl; }
real polyconn_distance_from(PolyConn *poly, Point *point, real line_width) { int i; real dist; dist = distance_line_point( &poly->points[0], &poly->points[1], line_width, point); for (i=1;i<poly->numpoints-1;i++) { dist = MIN(dist, distance_line_point( &poly->points[i], &poly->points[i+1], line_width, point)); } return dist; }
real distance_bez_line_point(const BezPoint *b, guint npoints, real line_width, const Point *point) { Point last; guint i; real line_dist = G_MAXFLOAT; g_return_val_if_fail(b[0].type == BEZ_MOVE_TO, -1); last = b[0].p1; for (i = 1; i < npoints; i++) { real dist; switch (b[i].type) { case BEZ_MOVE_TO: last = b[i].p1; break; case BEZ_LINE_TO: dist = distance_line_point(&last, &b[i].p1, line_width, point); line_dist = MIN(line_dist, dist); last = b[i].p1; break; case BEZ_CURVE_TO: dist = bez_point_distance_and_ray_crosses(&last, &b[i].p1, &b[i].p2, &b[i].p3, line_width, point, NULL); line_dist = MIN(line_dist, dist); last = b[i].p3; break; } } return line_dist; }
/*! * \brief Calculate BezCornerType just from the _BezPoint * * The bezier line/shape is fully described just with the array of BezPoint. * For convenience and editing there also is an BezierConn::corner_types. * This function adjust the corner types in the given array to match * the bezier points. */ static void bezier_calc_corner_types (BezierCommon *bezier) { int i; int num = bezier->num_points; const real tolerance = 0.00001; /* EPSILON */ g_return_if_fail (bezier->num_points > 1); bezier->corner_types = g_realloc (bezier->corner_types, bezier->num_points * sizeof(BezCornerType)); bezier->corner_types[0] = BEZ_CORNER_CUSP; bezier->corner_types[num-1] = BEZ_CORNER_CUSP; for (i = 0; i < num - 2; ++i) { const Point *start = &bezier->points[i].p2; const Point *major = &bezier->points[i].p3; const Point *end = &bezier->points[i+1].p2; if (bezier->points[i].type != BEZ_LINE_TO || bezier->points[i+1].type != BEZ_CURVE_TO) bezier->corner_types[i+1] = BEZ_CORNER_CUSP; else if (distance_point_point (start, end) < tolerance) /* last resort */ bezier->corner_types[i+1] = BEZ_CORNER_CUSP; else if (distance_line_point (start, end, 0, major) > tolerance) bezier->corner_types[i+1] = BEZ_CORNER_CUSP; else if (fabs ( distance_point_point (start, major) - distance_point_point (end, major) > tolerance)) bezier->corner_types[i+1] = BEZ_CORNER_SMOOTH; else bezier->corner_types[i+1] = BEZ_CORNER_SYMMETRIC; } }
static real arc_distance_from(Arc *arc, Point *point) { Point *endpoints; Point from_center; real angle; real d, d2; endpoints = &arc->connection.endpoints[0]; if (arc_is_line (arc)) return distance_line_point (&endpoints[0], &endpoints[1], arc->line_width, point); from_center = *point; point_sub(&from_center, &arc->center); angle = -atan2(from_center.y, from_center.x)*180.0/M_PI; if (angle<0) angle+=360.0; if (in_angle(angle, arc->angle1, arc->angle2)) { d = fabs(sqrt(point_dot(&from_center, &from_center)) - arc->radius); d -= arc->line_width/2.0; if (d<0) d = 0.0; return d; } else { d = distance_point_point(&endpoints[0], point); d2 = distance_point_point(&endpoints[1], point); return MIN(d,d2); } }
static real measure_distance_from (Measure *measure, Point *point) { return distance_line_point ( &measure->connection.endpoints[0], &measure->connection.endpoints[1], measure->line_width, point); }
static real line_distance_from(Line *line, Point *point) { Point *endpoints; endpoints = &line->connection.endpoints[0]; if (line->absolute_start_gap || line->absolute_end_gap ) { Point gap_endpoints[2]; /* Visible endpoints of line */ line_adjust_for_absolute_gap(line, gap_endpoints); return distance_line_point( &gap_endpoints[0], &gap_endpoints[1], line->line_width, point); } else { return distance_line_point( &endpoints[0], &endpoints[1], line->line_width, point); } }
static real line_distance_from(Line *line, Point *point) { Point *endpoints; endpoints = &line->connection.endpoints[0]; return distance_line_point( &endpoints[0], &endpoints[1], line->line_width, point); }
static real bus_distance_from(Bus *bus, Point *point) { Point *endpoints; real min_dist; int i; endpoints = &bus->real_ends[0]; min_dist = distance_line_point( &endpoints[0], &endpoints[1], LINE_WIDTH, point); for (i=0;i<bus->num_handles;i++) { min_dist = MIN(min_dist, distance_line_point( &bus->handles[i]->pos, &bus->parallel_points[i], LINE_WIDTH, point)); } return min_dist; }
real distance_bez_seg_point(const Point *b1, const BezPoint *b2, real line_width, const Point *point) { if (b2->type == BEZ_CURVE_TO) return bez_point_distance_and_ray_crosses(b1, &b2->p1, &b2->p2, &b2->p3, line_width, point, NULL); else return distance_line_point(b1, &b2->p1, line_width, point); }
void click_action(int button, int state,int x, int y) { if(button == GLUT_LEFT_BUTTON && state == GLUT_DOWN) { get_mouse_coordinates(x,y); float dist = INF; int i,stype,snum; for(i=0;i<num_projectors;i++) { float d = distance_line_point(projector[i].l,mouse.p); if(d<dist) { stype = PROJECTOR; snum = i; dist = d; } } for(i=0;i<num_mirrors;i++) { float d = distance_line_point(mirror[i].l,mouse.p); if(d<dist) { stype = MIRROR; snum = i; dist = d; } } for(i=0;i<num_blocks;i++) { float d = distance_line_point(block[i].l,mouse.p); if(d<dist) { stype = BLOCK; snum = i; dist = d; } } select_number = snum; select_type = stype; } }
static real annotation_distance_from(Annotation *annotation, Point *point) { Point *endpoints; Rectangle bbox; endpoints = &annotation->connection.endpoints[0]; text_calc_boundingbox(annotation->text,&bbox); return MIN(distance_line_point(&endpoints[0], &endpoints[1], ANNOTATION_LINE_WIDTH, point), distance_rectangle_point(&bbox,point)); }
static real message_distance_from(Message *message, Point *point) { Point *endpoints; real dist; endpoints = &message->connection.endpoints[0]; dist = distance_line_point(&endpoints[0], &endpoints[1], MESSAGE_WIDTH, point); return dist; }
int polyconn_closest_segment(PolyConn *poly, Point *point, real line_width) { int i; real dist; int closest; dist = distance_line_point( &poly->points[0], &poly->points[1], line_width, point); closest = 0; for (i=1;i<poly->numpoints-1;i++) { real new_dist = distance_line_point( &poly->points[i], &poly->points[i+1], line_width, point); if (new_dist < dist) { dist = new_dist; closest = i; } } return closest; }
static real constraint_distance_from(Constraint *constraint, Point *point) { Point *endpoints; real dist; endpoints = &constraint->connection.endpoints[0]; dist = distance_line_point(&endpoints[0], &endpoints[1], constraint->line_width, point); return dist; }
static real step_distance_from(Step *step, Point *point) { Element *elem = &step->element; Rectangle rect; real dist; dist = distance_line_point(&step->north.pos,&step->NU1, STEP_LINE_WIDTH,point); dist = MIN(dist,distance_line_point(&step->NU1,&step->NU2, STEP_LINE_WIDTH,point)); dist = MIN(dist,distance_line_point(&step->NU2,&step->A, STEP_LINE_WIDTH,point)); dist = MIN(dist,distance_line_point(&step->D,&step->SD1, STEP_LINE_WIDTH,point)); dist = MIN(dist,distance_line_point(&step->SD1,&step->SD2, STEP_LINE_WIDTH,point)); dist = MIN(dist,distance_line_point(&step->SD2,&step->south.pos, STEP_LINE_WIDTH,point)); rect.left = elem->corner.x; rect.right = elem->corner.x + elem->width; rect.top = elem->corner.y; rect.bottom = elem->corner.y + elem->height; dist = MIN(dist,distance_rectangle_point(&rect, point)); return dist; }
static real lifeline_distance_from(Lifeline *lifeline, Point *point) { Point *endpoints; real dist1, dist2; endpoints = &lifeline->connection.endpoints[0]; dist1 = distance_line_point( &endpoints[0], &endpoints[1], LIFELINE_WIDTH, point); dist2 = dist1; return MIN(dist1, dist2); }
static real flow_distance_from(Flow *flow, Point *point) { Point *endpoints; real linedist; real textdist; endpoints = &flow->connection.endpoints[0]; linedist = distance_line_point(&endpoints[0], &endpoints[1], flow->type == FLOW_MATERIAL ? FLOW_MATERIAL_WIDTH : FLOW_WIDTH, point); textdist = text_distance_from( flow->text, point ) ; return linedist > textdist ? textdist : linedist ; }
static real implements_distance_from(Implements *implements, Point *point) { Point *endpoints; real dist1, dist2; endpoints = &implements->connection.endpoints[0]; dist1 = distance_line_point( &endpoints[0], &endpoints[1], IMPLEMENTS_WIDTH, point); dist2 = distance_point_point( &implements->circle_center, point) - implements->circle_diameter/2.0; if (dist2<0) dist2 = 0; return MIN(dist1, dist2); }
/* if cross is not NULL, it will be incremented for each ray crossing */ static real bez_point_distance_and_ray_crosses(const Point *b1, const Point *b2, const Point *b3, const Point *b4, real line_width, const Point *point, guint *cross) { static gboolean calculated_coeff = FALSE; static real coeff[NBEZ_SEGS+1][4]; int i; real line_dist = G_MAXFLOAT; Point prev, pt; if (!calculated_coeff) { for (i = 0; i <= NBEZ_SEGS; i++) { real t1 = ((real)i)/NBEZ_SEGS, t2 = t1*t1, t3 = t1*t2; real it1 = 1-t1, it2 = it1*it1, it3 = it1*it2; coeff[i][0] = it3; coeff[i][1] = 3 * t1 * it2; coeff[i][2] = 3 * t2 * it1; coeff[i][3] = t3; } } calculated_coeff = TRUE; prev.x = coeff[0][0] * b1->x + coeff[0][1] * b2->x + coeff[0][2] * b3->x + coeff[0][3] * b4->x; prev.y = coeff[0][0] * b1->y + coeff[0][1] * b2->y + coeff[0][2] * b3->y + coeff[0][3] * b4->y; for (i = 1; i <= NBEZ_SEGS; i++) { real dist; pt.x = coeff[i][0] * b1->x + coeff[i][1] * b2->x + coeff[i][2] * b3->x + coeff[i][3] * b4->x; pt.y = coeff[i][0] * b1->y + coeff[i][1] * b2->y + coeff[i][2] * b3->y + coeff[i][3] * b4->y; dist = distance_line_point(&prev, &pt, line_width, point); line_dist = MIN(line_dist, dist); if (cross) *cross += line_crosses_ray(&prev, &pt, point); prev = pt; } return line_dist; }
real distance_bez_shape_point(const BezPoint *b, guint npoints, real line_width, const Point *point) { Point last; guint i; real line_dist = G_MAXFLOAT; guint crossings = 0; g_return_val_if_fail(b[0].type == BEZ_MOVE_TO, -1); last = b[0].p1; for (i = 1; i < npoints; i++) { real dist; switch (b[i].type) { case BEZ_MOVE_TO: /* no complains, there are renderers capable to handle this */ last = b[i].p1; break; case BEZ_LINE_TO: dist = distance_line_point(&last, &b[i].p1, line_width, point); crossings += line_crosses_ray(&last, &b[i].p1, point); line_dist = MIN(line_dist, dist); last = b[i].p1; break; case BEZ_CURVE_TO: dist = bez_point_distance_and_ray_crosses(&last, &b[i].p1, &b[i].p2, &b[i].p3, line_width, point, &crossings); line_dist = MIN(line_dist, dist); last = b[i].p3; break; } } /* If there is an odd number of ray crossings, we are inside the polygon. * Otherwise, return the minium distance from a line segment */ if (crossings % 2 == 1) return 0.0; else return line_dist; }
static int bus_point_near_handle(Bus *bus, Point *p) { int i, min; real dist = 1000.0; real d; min = -1; for (i=0;i<bus->num_handles;i++) { d = distance_line_point(&bus->parallel_points[i], &bus->handles[i]->pos, 0.0, p); if (d < dist) { dist = d; min = i; } } if (dist < 0.5) return min; else return -1; }
double distance_polygon_point(const Point *poly, int npoints, double lineWidth, const Point *point) { int i, last = npoints - 1; // double line_dist = G_MAXFLOAT; double line_dist = 1.0; int crossings = 0; for (i = 0; i < npoints; i++) { double dist; crossings += line_crosses_ray(&poly[last], &poly[i], point); dist = distance_line_point(&poly[last], &poly[i], lineWidth, point); line_dist = qMin(line_dist, dist); last = i; } if (crossings % 2 == 1) return 0.0; else return line_dist; }
real distance_polygon_point(const Point *poly, guint npoints, real line_width, const Point *point) { guint i, last = npoints - 1; real line_dist = G_MAXFLOAT; guint crossings = 0; /* calculate ray crossings and line distances */ for (i = 0; i < npoints; i++) { real dist; crossings += line_crosses_ray(&poly[last], &poly[i], point); dist = distance_line_point(&poly[last], &poly[i], line_width, point); line_dist = MIN(line_dist, dist); last = i; } /* If there is an odd number of ray crossings, we are inside the polygon. * Otherwise, return the minium distance from a line segment */ if (crossings % 2 == 1) return 0.0; else return line_dist; }
static real transition_distance_from(Transition *transition, Point *point) { real dist; dist = distance_rectangle_point(&transition->rceptbb,point); dist = MIN(dist,distance_line_point(&transition->C,&transition->D, TRANSITION_LINE_WIDTH,point)); dist = MIN(dist,distance_line_point(&transition->north.pos,&transition->NU1, TRANSITION_LINE_WIDTH,point)); dist = MIN(dist,distance_line_point(&transition->NU1,&transition->NU2, TRANSITION_LINE_WIDTH,point)); dist = MIN(dist,distance_line_point(&transition->NU2,&transition->SD1, TRANSITION_LINE_WIDTH,point)); /* A and B are on the [NU2; SD1] segment. */ dist = MIN(dist,distance_line_point(&transition->SD1,&transition->SD2, TRANSITION_LINE_WIDTH,point)); dist = MIN(dist,distance_line_point(&transition->SD2,&transition->south.pos, TRANSITION_LINE_WIDTH,point)); return dist; }