Beispiel #1
0
void wxGL_PMFCanvas::ray_pick(vector3d point, vector3d norm){
	int idx1=-1;
	int idx2=-1;
	float max_dist = FLT_MAX;
	for(unsigned int i = 0; i<omni.point.size(); i++){
		for(unsigned int j = 0; j< omni.point[i].size(); j++){

			float d = point_line_distance(omni.point[i][j].pos+model.get_model_offset(omni.point[i][j].model), point, norm);
			float rad = 0.0f;
			if(omni.flags & OMNIPOINT_ANY_PATH)//paths can have rediculusly huge radius's
				rad = log(omni.point[i][j].rad)+1.0f;
			else
				rad = omni.point[i][j].rad;
			if(d < rad && d<max_dist){
				max_dist = d;
				idx1 = i;
				idx2 = j;
			}
		}
	}
	if(idx1 >-1 && idx2 >-1){
		set_selected_omni_points(idx1, idx2);
		wxCommandEvent commandEvent(OMNIPOINT_RAY_PICKED, GetId());
		GetEventHandler()->ProcessEvent(commandEvent);
		Render();
	}
}
static void
normal_form (gdouble ax, gdouble ay,
	     gdouble bx, gdouble by,
	     gdouble * nx, gdouble * ny, gdouble * d)
{
    gdouble l;

    *nx = by - ay;
    *ny = ax - bx;

    l = length (*nx, *ny);

    *nx /= l;
    *ny /= l;

    *d = point_line_distance (ax, ay, *nx, *ny);
}
Beispiel #3
0
		inline void ramer_douglas_peucker_algorithm(const Polyline& poly, Polyline& nPoly, std::size_t start, std::size_t end, const Length& epsilon)
		{
			using access = point_sequence_traits<Polyline>;
			using point_t = typename access::point_type;
			using length_t = typename geometric_traits<point_t>::arithmetic_type;
			using dimensionless_t = typename geometric_traits<point_t>::dimensionless_type;
			using vector_t = vector<dimensionless_t, dimension_of<point_t>::value>;
			using line_t = line<point_t, vector_t>;

			// Find the point with the maximum distance
			auto dmax = constants::zero<length_t>();
			boost::optional<std::size_t> index;
			if ((start + 2) < end)
			{
				line_t l(access::get_point(poly, start), access::get_point(poly, end - 1));
				for (std::size_t i = start + 1; (i + 1) < end; ++i)
				{
					auto d = point_line_distance(access::get_point(poly, i), l);
					if (d > dmax)
					{
						index = i;
						dmax = d;
					}
				}
			}

			// If max distance is greater than epsilon, recursively simplify
			if (dmax > epsilon)
			{
				GEOMETRIX_ASSERT(index);
				ramer_douglas_peucker_algorithm(poly, nPoly, start, *index, epsilon);
				access::pop_back(nPoly);
				ramer_douglas_peucker_algorithm(poly, nPoly, *index, end, epsilon);
			}
			else
			{
				GEOMETRIX_ASSERT((start + 1) != end);
				access::push_back(nPoly, access::get_point(poly,start));
				access::push_back(nPoly, access::get_point(poly, end-1));
			}
		}
Beispiel #4
0
// point_line_distance
double
point_line_distance(BPoint point, BPoint pa, BPoint pb)
{
	// first figure out if point is between segment start and end points
	double a = point_point_distance(point, pb);
	double b = point_point_distance(point, pa);
	double c = point_point_distance(pa, pb);

	float currentDist = min_c(a, b);

	if (a > 0.0 && b > 0.0) {
		double alpha = acos((b*b + c*c - a*a) / (2*b*c));
		double beta = acos((a*a + c*c - b*b) / (2*a*c));

		if (alpha <= M_PI_2 && beta <= M_PI_2) {
			currentDist = fabs(point_line_distance(pa.x, pa.y, pb.x, pb.y,
				point.x, point.y));
		}
	}

	return currentDist;
}
Beispiel #5
0
// calc_angle
double
calc_angle(BPoint origin, BPoint from, BPoint to, bool degree)
{
	double angle = 0.0;

	double d = point_line_distance(from.x, from.y, origin.x, origin.y,
		to.x, to.y);
	if (d != 0.0) {
		double a = point_point_distance(from, to);
		double b = point_point_distance(from, origin);
		double c = point_point_distance(to, origin);
		if (a > 0.0 && b > 0.0 && c > 0.0) {
			angle = acos((b*b + c*c - a*a) / (2.0*b*c));

			if (d < 0.0)
				angle = -angle;

			if (degree)
				angle = angle * 180.0 / M_PI;
		}
	}
	return angle;
}
/* draw an angle from the current point to b and then to c,
 * with a rounded corner of the given radius.
 */
static void
rounded_corner (cairo_t * cr,
		gdouble bx, gdouble by,
		gdouble cx, gdouble cy, gdouble radius)
{
    gdouble ax, ay;
    gdouble n1x, n1y, d1;
    gdouble n2x, n2y, d2;
    gdouble pd1, pd2;
    gdouble ix, iy;
    gdouble dist1, dist2;
    gdouble nx, ny, d;
    gdouble a1x, a1y, c1x, c1y;
    gdouble phi1, phi2;

    cairo_get_current_point (cr, &ax, &ay);
#ifdef KBDRAW_DEBUG
    printf ("        current point: (%f, %f), radius %f:\n", ax, ay,
            radius);
#endif

    /* make sure radius is not too large */
    dist1 = length (bx - ax, by - ay);
    dist2 = length (cx - bx, cy - by);

    radius = MIN (radius, MIN (dist1, dist2));

    /* construct normal forms of the lines */
    normal_form (ax, ay, bx, by, &n1x, &n1y, &d1);
    normal_form (bx, by, cx, cy, &n2x, &n2y, &d2);

    /* find which side of the line a,b the point c is on */
    if (point_line_distance (cx, cy, n1x, n1y) < d1)
        pd1 = d1 - radius;
    else
        pd1 = d1 + radius;

    /* find which side of the line b,c the point a is on */
    if (point_line_distance (ax, ay, n2x, n2y) < d2)
        pd2 = d2 - radius;
    else
        pd2 = d2 + radius;

    /* intersect the parallels to find the center of the arc */
    intersect (n1x, n1y, pd1, n2x, n2y, pd2, &ix, &iy);

    nx = (bx - ax) / dist1;
    ny = (by - ay) / dist1;
    d = point_line_distance (ix, iy, nx, ny);

    /* a1 is the point on the line a-b where the arc starts */
    intersect (n1x, n1y, d1, nx, ny, d, &a1x, &a1y);

    nx = (cx - bx) / dist2;
    ny = (cy - by) / dist2;
    d = point_line_distance (ix, iy, nx, ny);

    /* c1 is the point on the line b-c where the arc ends */
    intersect (n2x, n2y, d2, nx, ny, d, &c1x, &c1y);

    /* determine the first angle */
    if (a1x - ix == 0)
        phi1 = (a1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
    else if (a1x - ix > 0)
        phi1 = atan ((a1y - iy) / (a1x - ix));
    else
        phi1 = M_PI + atan ((a1y - iy) / (a1x - ix));

    /* determine the second angle */
    if (c1x - ix == 0)
        phi2 = (c1y - iy > 0) ? M_PI_2 : 3 * M_PI_2;
    else if (c1x - ix > 0)
        phi2 = atan ((c1y - iy) / (c1x - ix));
    else
        phi2 = M_PI + atan ((c1y - iy) / (c1x - ix));

    /* compute the difference between phi2 and phi1 mod 2pi */
    d = phi2 - phi1;
    while (d < 0)
        d += 2 * M_PI;
    while (d > 2 * M_PI)
        d -= 2 * M_PI;

#ifdef KBDRAW_DEBUG
    printf ("        line 1 to: (%f, %f):\n", a1x, a1y);
#endif
    if (!(isnan (a1x) || isnan (a1y)))
        cairo_line_to (cr, a1x, a1y);

    /* pick the short arc from phi1 to phi2 */
    if (d < M_PI)
        cairo_arc (cr, ix, iy, radius, phi1, phi2);
    else
        cairo_arc_negative (cr, ix, iy, radius, phi1, phi2);

#ifdef KBDRAW_DEBUG
    printf ("        line 2 to: (%f, %f):\n", cx, cy);
#endif
    cairo_line_to (cr, cx, cy);
}