CubicSpline::CubicSpline(vector<Vector3> controlPoints, float tightness, int subDivisions) : m_length(0.f)
{
	Vector3 endTangent;
	for (int i = 0; i < controlPoints.size()-1; i++) {
		vector<Vector3> path;
		Vector3 start = controlPoints[i];
		Vector3 end = controlPoints[i+1];
		path.push_back(start);
		if (endTangent != Vector3::Zero) {
			// start tangent becomes the negative of the previous end tangent
			path.push_back(-endTangent + start);
		}
		
		
		if (i < controlPoints.size() - 2) {
			Vector3 next = controlPoints[i + 2];

			Vector3 line1 = start - end;
			Vector3 line2 = end - next;

			line1.Normalize();
			line2.Normalize();
			// average the two vectors to get the normal of reflection
			endTangent = Vector3((line1.x + line2.x) / 2.f, (line1.y + line2.y) / 2.f, (line1.z + line2.z) / 2.f);
			//endTangent.Normalize();
			endTangent *= tightness;
			path.push_back(endTangent + end);
		}
		path.push_back(end);
		Bezier bezier = Bezier(path);
		float length = bezier.Length(subDivisions);
		m_length += length;
		m_bezierSections.push_back(std::make_pair(Bezier(bezier), length));
	}
}
Beispiel #2
0
void draw_surface(float width, float height)
{
	/* pseudo
	1. calculate p3-p2
	2. set new bezier p0 = old bezier p3
	3. new beier p1 = p0 + old(p3-p2)*/

	Bezier tl = Bezier(width, height, angle);
	Vector4 d1 = tl.p3 - tl.p2;
	Vector4 d2 = tl.p7 - tl.p6;
	Vector4 d3 = tl.p11 - tl.p10;
	Vector4 d4 = tl.p15 - tl.p14;
	Vector4 g1 = tl.p3 + d1;
	Vector4 g2 = tl.p7 + d2;
	Vector4 g3 = tl.p11 + d3;
	Vector4 g4 = tl.p15 + d4;
	cout << "tlp7: " << tl.p7.y << endl;
	Bezier tr = Bezier(tl.p3, g1, tl.p7, g2,
						tl.p11, g3, tl.p15, g4, angle);
	//cout << "p0: " << tr.p0.y << " p3: " << tr.p3.y << " p12: " << tr.p12.y << " p15: " << tr.p15.y << endl;
	cout << "p4: " << tr.p4.y << " p8: " << tr.p8.y << " p7: " << tr.p7.y << " p11: " << tr.p11.y << endl;
	cout << "p5: " << tr.p5.y << endl;
	for (float t1 = -0.5; t1 < 0.49; t1 += 0.01)
	{
		for (float t2 = -0.5; t2 < 0.49; t2 += 0.01)
		{
			glColor3f(1, 0, 0);
			tl.tessellate(t1, t2, .1);
			glColor3f(0, 0, 1);
			tr.tessellate(t1, t2, .1);
		}
	}
}
Beispiel #3
0
void Polygon::Bezier(QImage *backBuffer, double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4,  QColor color){
    double m_distance_tolerance = 0.25;

    double x12  = (x1 + x2) / 2;
    double y12  = (y1 + y2) / 2;
    double x23  = (x2 + x3) / 2;
    double y23  = (y2 + y3) / 2;
    double x34  = (x3 + x4) / 2;
    double y34  = (y3 + y4) / 2;
    double x123  = (x12 + x23) / 2;
    double y123  = (y12 + y23) / 2;
    double x234  = (x23 + x34) / 2;
    double y234  = (y23 + y34) / 2;
    double x1234 = (x123 + x234) / 2;
    double y1234 = (y123 + y234) / 2;

    double dx = x4 - x1;
        double dy = y4-y1;

        double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx));
        double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx));


    if( (d2 + d3)*(d2 + d3) < m_distance_tolerance * (dx*dx + dy*dy) ){

        drawLine(backBuffer, x1, y1, x4, y4, color);
    }
    else{
        Bezier(backBuffer, x1, y1, x12, y12, x123, y123, x1234, y1234, color);
        Bezier(backBuffer, x1234, y1234, x234, y234, x34, y34, x4, y4, color);
    }
}
double Measurement::NearestPointOnCurve(QPointF P, vector<QPointF> V)

{
    QPointF	*w;			/* Ctl pts for 5th-degree eqn	*/
    double 	t_candidate[W_DEGREE];	/* Possible roots		*/
    int 	n_solutions;		/* Number of roots found	*/
    double	t;			/* Parameter value of closest pt*/

    QPointF v_arr[4];

    for(int i=0; i<4; i++)
        v_arr[i]=V[i];


    /*  Convert problem to 5th-degree Bezier form	*/
    w = ConvertToBezierForm(P, v_arr);

    /* Find all possible roots of 5th-degree equation */
    n_solutions = FindRoots(w, W_DEGREE, t_candidate, 0);
    free((char *)w);

    /* Compare distances of P to all candidates, and to t=0, and t=1 */
    {
        double 	dist, new_dist;
        QPointF 	p;
        QPointF  v;
        int		i;


        /* Check distance to beginning of curve, where t = 0	*/
        dist = V2SquaredLength(V2Sub(&P, &v_arr[0], &v));
        t = 0.0;

        /* Find distances for candidate points	*/
        for (i = 0; i < n_solutions; i++) {
            p = Bezier(v_arr, DEGREE, t_candidate[i],
                       (QPointF *)NULL, (QPointF *)NULL);
            new_dist = V2SquaredLength(V2Sub(&P, &p, &v));
            if (new_dist < dist) {
                dist = new_dist;
                t = t_candidate[i];
            }
        }

        /* Finally, look at distance to end point, where t = 1.0 */
        new_dist = V2SquaredLength(V2Sub(&P, &V[DEGREE], &v));
        if (new_dist < dist) {
            dist = new_dist;
            t = 1.0;
        }
    }

    /*  Return the point on the curve at parameter value t */
//    printf("t : %4.12f\n", t);
    QPointF b=Bezier(v_arr, DEGREE, t, (QPointF *)NULL, (QPointF *)NULL);
    return V2DistanceBetween2Points(&P,&b);

}
Beispiel #5
0
Point Bezier2D(Point p[4][4],float u,float v)
{
   float U = 1-u;
   float V = 1-v;
   Point P;
   P.x = Bezier(x);
   P.y = Bezier(y);
   P.z = Bezier(z);
   return P;
}
Beispiel #6
0
void setUpCurve(float d)
{
	blc = Vector3(-d, 0, -d);
	brc = Vector3(d, 0, -d);
	trc = Vector3(d, 0, d);
	tlc = Vector3(-d, 0, d);

	float dist = d / 3;

	if (cp == 1)
	{
		glColor3f(1, 0, 1);
		Matrix4 tc;
		Matrix4 t;

		t.makeTranslate(blc.x, blc.y, blc.z);
		tc = objCamera.c;
		tc = tc*t;
		tc.transpose();
		glLoadMatrixd(tc.getPointer());
		glutWireSphere(.5, 20, 20);

		t.makeTranslate(brc.x, brc.y, brc.z);
		tc = objCamera.c;
		tc = tc*t;
		tc.transpose();
		glLoadMatrixd(tc.getPointer());
		glutWireSphere(.5, 20, 20);

		t.makeTranslate(trc.x, trc.y, trc.z);
		tc = objCamera.c;
		tc = tc*t;
		tc.transpose();
		glLoadMatrixd(tc.getPointer());
		glutWireSphere(.5, 20, 20);

		t.makeTranslate(tlc.x, tlc.y, tlc.z);
		tc = objCamera.c;
		tc = tc*t;
		tc.transpose();
		glLoadMatrixd(tc.getPointer());
		glutWireSphere(.5, 20, 20);
	}

	glColor3f(0, 0, 1);
	x1 = Bezier(blc, Vector3(-dist, 0, -1.5*d), Vector3(dist, 0, -1.5*d), brc);
	glColor3f(1, 1, 0);
	x2 = Bezier(brc, Vector3(d*1.5, 0, -dist), Vector3(d*1.5, 0, dist), trc);
	glColor3f(1, 0, 0);
	x3 = Bezier(trc, Vector3(dist, 0, 1.5*d), Vector3(-dist, 0, 1.5*d), tlc);
	glColor3f(1, 1, 1);
	x4 = Bezier(tlc, Vector3(-1.5*d, 0, dist), Vector3(-1.5*d, 0, -dist), blc);
}
Beispiel #7
0
/* findHorizontal:
 * Given 4 Bezier control points pts, corresponding to the portion
 * of an initial spline with path parameter in the range
 * 0.0 <= tmin <= t <= tmax <= 1.0, return t where the spline 
 * first crosses a horizontal line segment
 * [(xmin,ycoord),(xmax,ycoord)]. Return -1 if not found.
 * This is done by binary subdivision. 
 */
static double
findHorizontal(pointf * pts, double tmin, double tmax,
	       double ycoord, double xmin, double xmax)
{
    pointf Left[4];
    pointf Right[4];
    double t;
    int no_cross = countHorzCross(pts, ycoord);

    if (no_cross == 0)
	return -1.0;

    /* if 1 crossing and on the line y == ycoord (within 1 point) */
    if ((no_cross == 1) && (ROUND(pts[3].y) == ROUND(ycoord))) {
	if ((xmin <= pts[3].x) && (pts[3].x <= xmax)) {
	    return tmax;
	} else
	    return -1.0;
    }

    /* split the Bezier into halves, trying the first half first. */
    Bezier(pts, 3, 0.5, Left, Right);
    t = findHorizontal(Left, tmin, (tmin + tmax) / 2.0, ycoord, xmin,
		       xmax);
    if (t >= 0.0)
	return t;
    return findHorizontal(Right, (tmin + tmax) / 2.0, tmax, ycoord, xmin,
			  xmax);
}
Beispiel #8
0
/* findVertical:
 * Given 4 Bezier control points pts, corresponding to the portion
 * of an initial spline with path parameter in the range
 * 0.0 <= tmin <= t <= tmax <= 1.0, return t where the spline 
 * first crosses a vertical line segment
 * [(xcoord,ymin),(xcoord,ymax)]. Return -1 if not found.
 * This is done by binary subdivision. 
 */
static double
findVertical(pointf * pts, double tmin, double tmax,
	     double xcoord, double ymin, double ymax)
{
    pointf Left[4];
    pointf Right[4];
    double t;
    int no_cross = countVertCross(pts, xcoord);

    if (no_cross == 0)
	return -1.0;

    /* if 1 crossing and on the line x == xcoord (within 1 point) */
    if ((no_cross == 1) && (ROUND(pts[3].x) == ROUND(xcoord))) {
	if ((ymin <= pts[3].y) && (pts[3].y <= ymax)) {
	    return tmax;
	} else
	    return -1.0;
    }

    /* split the Bezier into halves, trying the first half first. */
    Bezier(pts, 3, 0.5, Left, Right);
    t = findVertical(Left, tmin, (tmin + tmax) / 2.0, xcoord, ymin, ymax);
    if (t >= 0.0)
	return t;
    return findVertical(Right, (tmin + tmax) / 2.0, tmax, xcoord, ymin,
			ymax);

}
Beispiel #9
0
inline Coord *Line::clip(Coord *in, const Coord offset, const Region &reg, Coord *out) {
	double high = 1.0,
		low = 0.0;
	bool lowInside = reg.Hit(in[0]-offset),
		highInside = reg.Hit(in[degree]-offset);
	if(lowInside == highInside)
		return in;
	Coord work[4],
		*lowSeg,*highSeg;
	if(lowInside) {
		lowSeg = 0;
		highSeg = work;
	}
	else {
		lowSeg = work;
		highSeg = 0;
	}

	do {
		double t = (high + low) / 2.0;
		Coord p = Bezier(in,degree,t,lowSeg,highSeg);
		bool inside = reg.Hit(p-offset);
		if(inside == lowInside)
			low = t;
		else
			high = t;
	}
	while(high - low > DETAIL);	/* should be adaptive with resolution */
	for(int i=0;i<=degree;++i)
		out[i] = work[i];
	return out;
}
Beispiel #10
0
static  void
gd_bezier(point* A, int n, int arrow_at_start, int arrow_at_end)
{
	pointf		p0, p1, V[4];
	int		i, j, step;
	int		style[20]; 
	int		pen, width;
	gdImagePtr	brush = NULL;

	if (cstk[SP].pen != P_NONE) {
		if (cstk[SP].pen == P_DASHED) {
			for (i = 0; i < 10; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 20; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 20);
			pen = gdStyled;
		} else if (cstk[SP].pen == P_DOTTED) {
			for (i = 0; i < 2; i++)
				style[i] = cstk[SP].pencolor;
			for (; i < 12; i++)
				style[i] = gdTransparent;
			gdImageSetStyle(im, style, 12);
			pen = gdStyled;
		} else {
			pen = cstk[SP].pencolor;
		}
#if 0
                if (cstk[SP].penwidth != WIDTH_NORMAL) {
			width=cstk[SP].penwidth;
                        brush = gdImageCreate(width,width);
                        gdImagePaletteCopy(brush, im);
                        gdImageFilledRectangle(brush,
                           0,0,width-1, width-1, cstk[SP].pencolor);
                        gdImageSetBrush(im, brush);
			if (pen == gdStyled) pen = gdStyledBrushed;      
			else pen = gdBrushed;      
		}
#else
		width = cstk[SP].penwidth;
		gdImageSetThickness(im, width);
#endif
		V[3].x = A[0].x; V[3].y = A[0].y;
		for (i = 0; i+3 < n; i += 3) {
			V[0] = V[3];
			for (j = 1; j <= 3; j++) {
				V[j].x  = A[i+j].x; V[j].y = A[i+j].y;
			}
			p0 = gdpt(V[0]); 
			for (step = 1; step <= BEZIERSUBDIVISION; step++) {
				p1 = gdpt(Bezier(V, 3, (double)step/BEZIERSUBDIVISION, NULL, NULL));
				gdImageLine(im, ROUND(p0.x), ROUND(p0.y),
					ROUND(p1.x), ROUND(p1.y), pen);
				p0 = p1;
			}
		}
		if (brush)
			gdImageDestroy(brush);
	}
}
Beispiel #11
0
pointf dotneato_closest(splines * spl, pointf pt)
{
    int i, j, k, besti, bestj;
    double bestdist2, d2, dlow2, dhigh2; /* squares of distances */
    double low, high, t;
    pointf c[4], pt2;
    bezier bz;

    besti = bestj = -1;
    bestdist2 = 1e+38;
    for (i = 0; i < spl->size; i++) {
	bz = spl->list[i];
	for (j = 0; j < bz.size; j++) {
	    pointf b;

	    b.x = bz.list[j].x;
	    b.y = bz.list[j].y;
	    d2 = DIST2(b, pt);
	    if ((bestj == -1) || (d2 < bestdist2)) {
		besti = i;
		bestj = j;
		bestdist2 = d2;
	    }
	}
    }

    bz = spl->list[besti];
    /* Pick best Bezier. If bestj is the last point in the B-spline, decrement.
     * Then set j to be the first point in the corresponding Bezier by dividing
     * then multiplying be 3. Thus, 0,1,2 => 0; 3,4,5 => 3, etc.
     */
    if (bestj == bz.size-1)
	bestj--;
    j = 3*(bestj / 3);
    for (k = 0; k < 4; k++) {
	c[k].x = bz.list[j + k].x;
	c[k].y = bz.list[j + k].y;
    }
    low = 0.0;
    high = 1.0;
    dlow2 = DIST2(c[0], pt);
    dhigh2 = DIST2(c[3], pt);
    do {
	t = (low + high) / 2.0;
	pt2 = Bezier(c, 3, t, NULL, NULL);
	if (fabs(dlow2 - dhigh2) < 1.0)
	    break;
	if (fabs(high - low) < .00001)
	    break;
	if (dlow2 < dhigh2) {
	    high = t;
	    dhigh2 = DIST2(pt2, pt);
	} else {
	    low = t;
	    dlow2 = DIST2(pt2, pt);
	}
    } while (1);
    return pt2;
}
Beispiel #12
0
point spline_at_y(splines *spl, int y)
{
	int i,j;
	double low, high, d, t;
	pointf c[4], pt2;
	point pt;
	static bezier bz;
	static splines *mem = NULL;

	if (mem != spl) {
		mem = spl;
		for (i = 0; i < spl->size; i++) {
			bz = spl->list[i];
			if (BETWEEN (bz.list[bz.size-1].y, y, bz.list[0].y))
				break;
		}
	}
	if (y > bz.list[0].y)
		pt = bz.list[0];
	else if (y < bz.list[bz.size-1].y)
		pt = bz.list[bz.size - 1];
	else {
		for (i = 0; i < bz.size; i += 3) {
			for (j = 0; j < 3; j++) {
				if ((bz.list[i+j].y <= y) && (y <= bz.list[i+j+1].y))
					break;
				if ((bz.list[i+j].y >= y) && (y >= bz.list[i+j+1].y))
					break;
			}
			if (j < 3)
				break;
		}
		assert (i < bz.size);
		for (j = 0; j < 4; j++) {
			c[j].x = bz.list[i + j].x;
			c[j].y = bz.list[i + j].y;
			/* make the spline be monotonic in Y, awful but it works for now */
			if ((j > 0) && (c[j].y > c[j - 1].y))
				c[j].y = c[j - 1].y;
		}
		low = 0.0; high = 1.0;
		do {
			t = (low + high) / 2.0;
			pt2 = Bezier (c, 3, t, NULL, NULL);
			d = pt2.y - y;
			if (ABS(d) <= 1)
				break;
			if (d < 0)
				high = t;
			else
				low = t;
		} while (1);
		pt.x = (int)pt2.x;
		pt.y = (int)pt2.y;
	}
	pt.y = y;
	return pt;
}
Beispiel #13
0
point dotneato_closest(splines * spl, point p)
{
    int i, j, k, besti, bestj;
    double bestdist2, d2, dlow2, dhigh2; /* squares of distances */
    double low, high, t;
    pointf c[4], pt2, pt;
    point rv;
    bezier bz;

    besti = bestj = -1;
    bestdist2 = 1e+38;
    P2PF(p, pt);
    for (i = 0; i < spl->size; i++) {
	bz = spl->list[i];
	for (j = 0; j < bz.size; j++) {
	    pointf b;

	    b.x = bz.list[j].x;
	    b.y = bz.list[j].y;
	    d2 = DIST2(b, pt);
	    if ((bestj == -1) || (d2 < bestdist2)) {
		besti = i;
		bestj = j;
		bestdist2 = d2;
	    }
	}
    }

    bz = spl->list[besti];
    j = bestj / 3;
    if (j >= spl->size)
	j--;
    for (k = 0; k < 4; k++) {
	c[k].x = bz.list[j + k].x;
	c[k].y = bz.list[j + k].y;
    }
    low = 0.0;
    high = 1.0;
    dlow2 = DIST2(c[0], pt);
    dhigh2 = DIST2(c[3], pt);
    do {
	t = (low + high) / 2.0;
	pt2 = Bezier(c, 3, t, NULL, NULL);
	if (fabs(dlow2 - dhigh2) < 1.0)
	    break;
	if (fabs(high - low) < .00001)
	    break;
	if (dlow2 < dhigh2) {
	    high = t;
	    dhigh2 = DIST2(pt2, pt);
	} else {
	    low = t;
	    dlow2 = DIST2(pt2, pt);
	}
    } while (1);
    PF2P(pt2, rv);
    return rv;
}
void VectorFileWriter::BezierAsPwl(SBezier *sb) {
    List<Vector> lv;
    ZERO(&lv);
    sb->MakePwlInto(&lv, SS.ChordTolMm() / SS.exportScale);
    int i;
    for(i = 1; i < lv.n; i++) {
        SBezier sb = SBezier::From(lv.elem[i-1], lv.elem[i]);
        Bezier(&sb);
    }
    lv.Clear();
}
Beispiel #15
0
/* splineIntersectf:
 * Given four spline control points and a box,
 * find the shortest portion of the spline from
 * pts[0] to the intersection with the box, if any.
 * If an intersection is found, the four points are stored in pts[0..3]
 * with pts[3] being on the box, and 1 is returned. Otherwise, pts
 * is left unchanged and 0 is returned.
 */
static int splineIntersectf(pointf * pts, boxf * bb)
{
    double tmin = 2.0;
    double t;
    pointf origpts[4];
    int i;

    for (i = 0; i < 4; i++) {
	origpts[i] = pts[i];
    }

    t = findVertical(pts, 0.0, 1.0, bb->LL.x, bb->LL.y, bb->UR.y);
    if ((t >= 0) && (t < tmin)) {
	Bezier(origpts, 3, t, pts, NULL);
	tmin = t;
    }
    t = findVertical(pts, 0.0, MIN(1.0, tmin), bb->UR.x, bb->LL.y,
		     bb->UR.y);
    if ((t >= 0) && (t < tmin)) {
	Bezier(origpts, 3, t, pts, NULL);
	tmin = t;
    }
    t = findHorizontal(pts, 0.0, MIN(1.0, tmin), bb->LL.y, bb->LL.x,
		       bb->UR.x);
    if ((t >= 0) && (t < tmin)) {
	Bezier(origpts, 3, t, pts, NULL);
	tmin = t;
    }
    t = findHorizontal(pts, 0.0, MIN(1.0, tmin), bb->UR.y, bb->LL.x,
		       bb->UR.x);
    if ((t >= 0) && (t < tmin)) {
	Bezier(origpts, 3, t, pts, NULL);
	tmin = t;
    }

    if (tmin < 2.0) {
	return 1;
    } else
	return 0;
}
Beispiel #16
0
void Bezier(HDC hDC, double x1, double y1, double x2, double y2, 
			         double x3, double y3, double x4, double y4)
{
	double A = y4 - y1;
	double B = x1 - x4;
	double C = y1 * (x4-x1) - x1 * ( y4-y1);
	// Ax + By + C = 0  is line (x1,y1) - (x4,y4)

	double AB  = A * A + B * B;

	// distance from (x2,y2) to the line is less than 1
	// distance from (x3,y3) to the line is less than 1
	if ( ( A * x2 + B * y2 + C ) * ( A * x2 + B * y2 + C ) < AB )
	if ( ( A * x3 + B * y3 + C ) * ( A * x3 + B * y3 + C ) < AB )
	{
		MoveToEx(hDC, (int)x1, (int)y1, NULL);
		LineTo(hDC, (int)x4, (int)y4);

		return;
	}
	
	double x12   = x1+x2;
	double y12   = y1+y2;
	double x23   = x2+x3;
	double y23   = y2+y3;
	double x34   = x3+x4;
	double y34   = y3+y4;

	double x1223 = x12+x23;
	double y1223 = y12+y23;
	double x2334 = x23+x34;
	double y2334 = y23+y34;

	double x     = x1223 + x2334;
	double y     = y1223 + y2334;

	Bezier(hDC, x1, y1, x12/2, y12/2, x1223/4, y1223/4, x/8, y/8);
	Bezier(hDC, x/8, y/8, x2334/4, y2334/4, x34/2, y34/2, x4, y4);
}
Beispiel #17
0
int main()
{
    int gdriver=DETECT,gmode;
    initgraph(&gdriver,&gmode," ");
    cleardevice();
    int i;

    memset(B,0,sizeof(B));//初始化数组全为0
    memset(P,0,sizeof(P));
    for(i=0;i<sizeof(t)/sizeof(double);i++)
    {
        B[i][0]=(1-t[i])*(1-t[i])*(1-t[i]);
        B[i][1]=3*t[i]*(1-t[i])*(1-t[i]);
        B[i][2]=3*t[i]*t[i]*(1-t[i]);
        B[i][3]=t[i]*t[i]*t[i];
    }
    /*for(i=0;i<7;i++)
    {
        for(j=0;j<4;j++)
        {
            printf("%f ",B[i][j]);
        }
        printf("\n");
    }*/                                 //输出B矩阵
    Bezier(50,100, 80,230, 100,270 ,140,160);
    Bezier(140,160, 180,50, 240,65, 270,120);
    Bezier(270,120, 330,230, 380,230, 430,150);
    /*for(i=0;i<7;i++)
    {
        for(j=0;j<2;j++)
        {
            printf("%f ",P[i][j]);
        }
        printf("\n");
    }*/                                 //输出P矩阵
    getch();
    closegraph();
    return 0;
}
Beispiel #18
0
void Draw_Bezier(float width, float height)
{
	float x = width / 2;
	float y = height / 2;

	Matrix4 t;
	t.makeTranslate(-x, -y, 0);

	Matrix4 c = objCamera.c;
	c = t*c;
	c.transpose();
	glLoadMatrixd(c.getPointer());
	glColor3f(0, 0, 1);
	my = Bezier(width, height, angle);
	for (float t1 = -0.5; t1 < 0.49; t1 += 0.01)
	{
		for (float t2 = -0.5; t2 < 0.49; t2 += 0.01)
		{
			my.tessellate(t1, t2, .1);
		}
	}

	t.makeTranslate(x, -y, 0);
	c = objCamera.c;
	c = t*c;
	c.transpose();
	glLoadMatrixd(c.getPointer());

	glColor3f(1, 0, 0);
	my2 = Bezier(width, height, angle);
	for (float t1 = -0.5; t1 < 0.49; t1 += 0.01)
	{
		for (float t2 = -0.5; t2 < 0.49; t2 += 0.01)
		{
			my.tessellate(t1, t2, .1);
		}
	}
}
Beispiel #19
0
QImage Polygon::getImage(int width, int height) {
    this->width = width;
    this->height = height;

    lines.clear();

    QImage backBuffer(width, height, QImage::Format_RGB888);
    backBuffer.fill(qRgb(255, 255, 255));

    //drawBezier(&backBuffer, Qt::black);
    Bezier(&backBuffer, points[0].x(),points[0].y(), points[1].x(), points[1].y(), points[2].x(), points[2].y(), points[3].x(), points[3].y(), Qt::black);

    return backBuffer;
}
Beispiel #20
0
point dotneato_closest(splines* spl, point p)
{
	int		i, j, k, besti, bestj;
	double	bestdist, d, dlow, dhigh;
	double low, high, t;
	pointf c[4], pt2, pt;
	point rv;
	bezier bz;

	besti = bestj = -1;
	bestdist = 1e+38;
	pt.x = p.x; pt.y = p.y;
	for (i = 0; i < spl->size; i++) {
		bz = spl->list[i];
		for (j = 0; j < bz.size; j++) {
			pointf b;

			b.x = bz.list[j].x; b.y = bz.list[j].y;
			d = dist(b,pt);
			if ((bestj == -1) || (d < bestdist)) {
				besti = i;
				bestj = j;
				bestdist = d;
			}
		}
	}

	bz = spl->list[besti];
	j = bestj/3; if (j >= spl->size) j--;
	for (k = 0; k < 4; k++) {
		c[k].x = bz.list[j + k].x;
		c[k].y = bz.list[j + k].y;
	}
	low = 0.0; high = 1.0;
	dlow = dist(c[0],pt);
	dhigh = dist(c[3],pt);
	do {
		t = (low + high) / 2.0;
		pt2 = Bezier (c, 3, t, NULL, NULL);
		if (fabs(dlow - dhigh) < 1.0) break;
		if (low == high) break;
		if (dlow < dhigh) {high = t; dhigh = dist(pt2,pt);}
		else {low = t; dlow = dist(pt2,pt); }
	} while (1);
	rv.x = (int)pt2.x;
	rv.y = (int)pt2.y;
	return rv;
}
static void
vrml_bezier(GVJ_t *job, pointf * A, int n, int arrow_at_start, int arrow_at_end, int filled)
{
    obj_state_t *obj = job->obj;
    edge_t *e = obj->u.e;
    double fstz, sndz;
    pointf p1, V[4];
    int i, j, step;

    assert(e);

    fstz = Fstz = obj->tail_z; 
    sndz = Sndz = obj->head_z;
    if (straight(A,n)) {
	doSegment (job, A, gvrender_ptf(job, ND_coord(agtail(e))),Fstz,gvrender_ptf(job, ND_coord(aghead(e))),Sndz);
	return;
    }

    gvputs(job,   "Shape { geometry Extrusion  {\n");
    gvputs(job,   "  spine [");
    V[3] = A[0];
    for (i = 0; i + 3 < n; i += 3) {
	V[0] = V[3];
	for (j = 1; j <= 3; j++)
	    V[j] = A[i + j];
	for (step = 0; step <= BEZIERSUBDIVISION; step++) {
	    p1 = Bezier(V, 3, (double) step / BEZIERSUBDIVISION, NULL, NULL);
	    gvprintf(job, " %.3f %.3f %.3f", p1.x, p1.y,
		    interpolate_zcoord(job, p1, A[0], fstz, A[n - 1], sndz));
	}
    }
    gvputs(job,   " ]\n");
    gvprintf(job, "  crossSection [ %.3f %.3f, %.3f %.3f, %.3f %.3f, %.3f %.3f ]\n",
	    (obj->penwidth), (obj->penwidth), -(obj->penwidth),
	    (obj->penwidth), -(obj->penwidth), -(obj->penwidth),
	    (obj->penwidth), -(obj->penwidth));
    gvputs(job,   "}\n");
    gvprintf(job, " appearance DEF E%ld Appearance {\n", AGSEQ(e));
    gvputs(job,   "   material Material {\n");
    gvputs(job,   "   ambientIntensity 0.33\n");
    gvprintf(job, "   diffuseColor %.3f %.3f %.3f\n",
	    obj->pencolor.u.rgba[0] / 255.,
	    obj->pencolor.u.rgba[1] / 255.,
	    obj->pencolor.u.rgba[2] / 255.);
    gvputs(job,   "   }\n");
    gvputs(job,   " }\n");
    gvputs(job,   "}\n");
}
/*
 *  FindRoots :
 *	Given a 5th-degree equation in Bernstein-Bezier form, find
 *	all of the roots in the interval [0, 1].  Return the number
 *	of roots found.
 */
int Measurement::FindRoots(QPointF* w, int degree,double *t,int depth)
{
    int 	i;
    QPointF 	Left[W_DEGREE+1],	/* New left and right 		*/
            Right[W_DEGREE+1];	/* control polygons		*/
    int 	left_count,		/* Solution count from		*/
            right_count;		/* children			*/
    double 	left_t[W_DEGREE+1],	/* Solutions from kids		*/
            right_t[W_DEGREE+1];

    switch (CrossingCount(w, degree)) {
    case 0 : {	/* No solutions here	*/
        return 0;
    }
    case 1 : {	/* Unique solution	*/
        /* Stop recursion when the tree is deep enough	*/
        /* if deep enough, return 1 solution at midpoint 	*/
        if (depth >= MAXDEPTH) {
            t[0] = (w[0].rx() + w[W_DEGREE].rx()) / 2.0;
            return 1;
        }
        if (ControlPolygonFlatEnough(w, degree)) {
            t[0] = ComputeXIntercept(w, degree);
            return 1;
        }
        break;
    }
    }

    /* Otherwise, solve recursively after	*/
    /* subdividing control polygon		*/
    Bezier(w, degree, 0.5, Left, Right);
    left_count  = FindRoots(Left,  degree, left_t, depth+1);
    right_count = FindRoots(Right, degree, right_t, depth+1);


    /* Gather solutions together	*/
    for (i = 0; i < left_count; i++) {
        t[i] = left_t[i];
    }
    for (i = 0; i < right_count; i++) {
        t[i+left_count] = right_t[i];
    }

    /* Send back total number of solutions	*/
    return (left_count+right_count);
}
/*
 *  find_bezier_roots : Given an equation in Bernstein-Bezier form, find all 
 *    of the roots in the interval [0, 1].  Return the number of roots found.
 */
void
find_parametric_bezier_roots(Geom::Point const *w, /* The control points  */
                  unsigned degree,	/* The degree of the polynomial */
                  std::vector<double> &solutions, /* RETURN candidate t-values */
                  unsigned depth)	/* The depth of the recursion */
{  
    total_steps++;
    const unsigned max_crossings = crossing_count(w, degree);
    switch (max_crossings) {
    case 0: 	/* No solutions here	*/
        return;
	
    case 1:
 	/* Unique solution	*/
        /* Stop recursion when the tree is deep enough	*/
        /* if deep enough, return 1 solution at midpoint  */
        if (depth >= MAXDEPTH) {
            solutions.push_back((w[0][Geom::X] + w[degree][Geom::X]) / 2.0);
            return;
        }
        
        // I thought secant method would be faster here, but it'aint. -- njh

        if (control_poly_flat_enough(w, degree)) {
            solutions.push_back(compute_x_intercept(w, degree));
            return;
        }
        break;
    }

    /*
     * Otherwise, solve recursively after subdividing control polygon
     * New left and right control polygons
     */
    Geom::Point *Left  = new Geom::Point[degree+1];
    Geom::Point *Right = new Geom::Point[degree+1];

    Bezier(w, degree, 0.5, Left, Right);
    total_subs ++;
    find_parametric_bezier_roots(Left,  degree, solutions, depth+1);
    find_parametric_bezier_roots(Right, degree, solutions, depth+1);

    delete[] Left;
    delete[] Right;
}
Beispiel #24
0
void Shape::addBezier(vector<Point> *result) {
    vector<Point> temp;
    temp = points;
    for(int i=0; i<temp.size(); i++) {
       
        if(temp[i].tag==0) {

            vector<Point> control;
            vector<Point> bezier;
            control.push_back(temp[i]);
            i++;
            while(i<temp.size() && temp[i].tag==1) {

                control.push_back(temp[i]);
                i++;
            }
            if(i>=temp.size()) {
                control.push_back(temp[0]);
               
            }
            else {
                control.push_back(temp[i]);
                if(i>=temp.size())
                control.push_back(temp[0]);
            }
            //jika isi control>2, berarti bezier
           
            if(control.size()>2) {
                Bezier(control, &bezier);
                for(int j=0; j<bezier.size(); j++){
                    result->push_back(bezier[j]);
                }
                
               
            }
            else {
                for(int j=0; j<control.size(); j++){
                    result->push_back(control[j]);
                }
            }
            i--;
        }
    }
}
Beispiel #25
0
void Style::active_bezier() {
	if (npara == 3) {
		graybg();
		int centerx, centery, a = parameters[2];
		if (item) {
			centerx = item->layer->startx + parameters[0];
			centery = item->layer->starty + parameters[1];
		}
		setcolor(BLACK);
		if (item) {
			rectangle(item->layer->startx, item->layer->starty, item->layer->endx, item->layer->endy);
		}
		vector<Point> control;
		control.push_back(Point(centerx, item->layer->starty));
		control.push_back(Point(item->layer->startx, centery - a / 2));
		control.push_back(Point(item->layer->endx, centery + a / 2));
		control.push_back(Point(centerx, item->layer->endy));
		Bezier(control, BLACK);
	}
}
Beispiel #26
0
Position Line::Intersection(int seg,Segment other) {
	switch(degree) {
	case 1:
		return lines_intersect(Segment(at(seg),at(seg+1)),other);
	case 3:
		double roots[4];
		/*
		if(between(other.a,at(seg),other.b))
			return Position(at(seg));
		if(between(other.a,at(seg+3),other.b))
			return Position(at(seg+3));
			*/
		if(splineIntersectsLine(&at(seg),other,roots)>0)
			return Position(Bezier(&at(seg),3,roots[0]));
		else
			return Position();
	default:
	case 0:
		return Position();
	}
}
void VectorFileWriter::BezierAsNonrationalCubic(SBezier *sb, int depth) {
    Vector t0 = sb->TangentAt(0), t1 = sb->TangentAt(1);
    // The curve is correct, and the first derivatives are correct, at the
    // endpoints.
    SBezier bnr = SBezier::From(
                        sb->Start(),
                        sb->Start().Plus(t0.ScaledBy(1.0/3)),
                        sb->Finish().Minus(t1.ScaledBy(1.0/3)),
                        sb->Finish());

    double tol = SS.ChordTolMm() / SS.exportScale;
    // Arbitrary choice, but make it a little finer than pwl tolerance since
    // it should be easier to achieve that with the smooth curves.
    tol /= 2;

    bool closeEnough = true;
    int i;
    for(i = 1; i <= 3; i++) {
        double t = i/4.0;
        Vector p0 = sb->PointAt(t),
               pn = bnr.PointAt(t);
        double d = (p0.Minus(pn)).Magnitude();
        if(d > tol) {
            closeEnough = false;
        }
    }
    
    if(closeEnough || depth > 3) {
        Bezier(&bnr);
    } else {
        SBezier bef, aft;
        sb->SplitAt(0.5, &bef, &aft);
        BezierAsNonrationalCubic(&bef, depth+1);
        BezierAsNonrationalCubic(&aft, depth+1);
    }
}
Beispiel #28
0
Position Line::YIntersection(double y) {
	if(!size())
		return Position();
	for(unsigned i = 0; i < size(); i += degree)
		if(at(i).y == y)
			return Position(at(i));
	int seg = GetSeg(y);
	if(seg < 0)
		return Position();
	double high,low;
	if(at(seg).y < at(seg+degree).y) {
		high = 1.0;
		low = 0.0;
	}
	else  {
		high = 0.0;
		low = 1.0;
	}
	double close = DBL_MAX;
	Coord ret;
	do {
		double t = (high + low) / 2.0;
		Coord p = Bezier(&at(seg),degree,t);
		double d = absol(p.y - y);
		if(d < close) {
			ret = p;
			close = d;
		}
		if(p.y > y)
			high = t;
		else
			low = t;
	}
	while(absol(high - low) > .01); /* should be adaptive */
	return Position(ret);
}
Beispiel #29
0
void Style::normal_bezier() {
	if (npara == 3) {
		setlinestyle(SOLID_LINE, 0, NORM_WIDTH);
		setfillstyle(SOLID_FILL, WHITE);
		if (item) {
			bar(item->layer->startx + 1, item->layer->starty + 1, item->layer->endx, item->layer->endy);
		}
		int centerx, centery, a = parameters[2];
		if (item) {
			centerx = item->layer->startx + parameters[0];
			centery = item->layer->starty + parameters[1];
		}
		setcolor(BLACK);
		if (item) {
			rectangle(item->layer->startx, item->layer->starty, item->layer->endx, item->layer->endy);
		}
		vector<Point> control;
		control.push_back(Point(centerx, item->layer->starty));
		control.push_back(Point(item->layer->startx, centery - a / 2));
		control.push_back(Point(item->layer->endx, centery + a / 2));
		control.push_back(Point(centerx, item->layer->endy));
		Bezier(control, BLACK);
	}
}
Beispiel #30
0
//Display
void display (void) 
{ 
    glClearColor(rosso_sf,verde_sf,blu_sf,0.0);//rendo variabili i parametri che mi definiscono il colore 
    glClear(GL_COLOR_BUFFER_BIT); 
    int i; 

    glColor3f(0.0,0.0,1.0); 
    glPointSize(dimpunto); 
    glBegin(GL_POINTS);//per visualizzare anche i punti dove si clicca di colore blu
        for (i=1;i<=last;i++) 
            glVertex2f(Punti[i].x,Punti[i].y); 
    glEnd(); 
    glColor3f(rosso_dis,verde_dis,blu_dis); 
    glBegin(GL_LINE_STRIP); //poligono di controllo
        for (i=1;i<=last;i++) 
            glVertex2f(Punti[i].x,Punti[i].y); 
    glEnd(); 
    n=last;//setto n al numero di punti disegnato
  
	for(i=1;i<=n;i++)
		w[i]=1;//metto tutti i pesi a 1

	//scelta parametrizzazione
    if (scelta_param==0) 
    { 
        Parametrizzazione_Uniforme();    
    } 
    else if(scelta_param==1) 
    { 
        Parametrizzazione_Corde(); 
    } 
  
	//scelta della funzione
	glPointSize(2);//la curva la disegno sempre di dimensione 2
    if (metodo=='H' && last>1) 
    { 
        Hermite(); 
        Disegna_Funzioni_Base(); 
    } 
  
    if (metodo=='B' && last>1) 
    { 
        if(mod_pesi_bez==1)
			w[i_p_b]=val_peso;
		Bezier(); 
        if (subd==1) 
            Subdivision(); 
        if (d_el==1) 
            Degree_Elevation(); 
        Disegna_fBaseBernstein(); 
    } 
  
    if (metodo=='S' && last>3) 
    { 
        if(mod_pesi_spline==1)
			w[i_p_s]=val_pesos;
		Costruisci_Nodi(); 
        Funzioni_Bspline(Nodi); 
        De_Boor();   
    } 
    //glutPostRedisplay();//è per questo che le funzioni base saltellano :)...se non lo metti però quando cambi il metodo non viene cambiato immediatamente ma dopo aver spinto un altro punto 
    glFlush(); 
}