Пример #1
0
void CBCStroke::DrawBezierCurve(FCObjImage& img,BezierPressCurve& bezpCurve,BYTE alpha,float zoompaper,float zoompress)
{
	double t,delt;
	//delt=(double)1/bezpCurve.numpoint;
	TPosition position;
	t=0.0;
	int x1,y1,x2,y2;
	x1=y1=x2=y2=0;
	BezierCurve bezCurve=new Point2[bezpCurve.degree+1];
	for(int i=0;i<=bezpCurve.degree;++i){
		bezCurve[i].x=zoompaper*(bezpCurve.bezCurve[i].x);
		bezCurve[i].y=zoompaper*(bezpCurve.bezCurve[i].y);
	}
/*	for(int i=0;i<=bezpCurve.degree;++i){
		bezpCurve.bezCurve[i].x=zoompaper*(bezpCurve.bezCurve[i].x);
		bezpCurve.bezCurve[i].y=zoompaper*(bezpCurve.bezCurve[i].y);
	}*/
	float numpoint=0;
	if(bezpCurve.degree>=2){
		numpoint=V2DistanceBetween2Points(&(bezCurve[0]),&(bezCurve[1]));
		for (int i =1; i <bezpCurve.degree; i++) {
			numpoint+=V2DistanceBetween2Points(&(bezCurve[i]),&(bezCurve[i+1]));
		}
	}
	
	numpoint=numpoint*2;
	if(numpoint<=0)
		return;
	delt=(double)1/numpoint;
	bezpCurve.numpoint=0;
	for(int i=0;i<=numpoint;++i){				
		Point2 p=CBCStroke::BezierII(bezpCurve.degree,bezCurve,t);
		//if(i==numpoint)
		//	continue;
		x1=p.x;
		y1=p.y;
		if(x1!=x2||y1!=y2){
			PARAMER param;
			//CStrokeTransform::GenParamer(bezpCurve.uList,t,param);
			position.press=param.press*zoompress;
			position.press=(position.press<1)?1:position.press;
			position.m_angle_z=param.m_angle_z;
			position.m_angle_xy=param.m_angle_xy;
			position.m_x=x1;
			position.m_y=y1;
			m_lpPaper->DrawSection(img,position,alpha);
			x2=x1;
			y2=y1;
			bezpCurve.numpoint++;
		}	
		t+=delt;
	}														
}
Пример #2
0
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);

}
Пример #3
0
//------------------------------------------------------
//----计算u为t时的bezier曲线的近似长度。
double BezierPressCurve::GetLengthFromParam(double t,double t_begin,double error)
{
	Point2 p1=CBCStroke::BezierII(degree,bezCurve,t_begin);	
	Point2 p2=CBCStroke::BezierII(degree,bezCurve,t);
	double length=V2DistanceBetween2Points(&p1,&p2);
	if((length>error)||(fabs(t-t_begin)>=0.25)){
		length=GetLengthFromParam((t+t_begin)/2,t_begin,error)+GetLengthFromParam(t,(t+t_begin)/2,error);
	}
	return length;
}
Пример #4
0
void CBCStroke::AddBezierCurve(int degree,BezierCurve bezCurve,PARAMERLIST& paramList)
{
	BezierPressCurve bezpCurve;
	bezpCurve.degree=degree;
	bezpCurve.bezCurve = (Point2 *)malloc((unsigned)((degree+1) 
		* sizeof (Point2)));
	//for(int i=0;i<=degree;++i){
	//	bezpCurve.bezCurve[i].x=bezCurve[i].x;
	//	bezpCurve.bezCurve[i].y=bezCurve[i].y;
	//}
	memcpy(bezpCurve.bezCurve,bezCurve,(degree+1) * sizeof (Point2));
	double numpoint=0;
	if(degree>=2){
		numpoint=V2DistanceBetween2Points(&(bezCurve[0]),&(bezCurve[1]));
		for (int i =1; i <degree; i++) {
			numpoint+=V2DistanceBetween2Points(&(bezCurve[i]),&(bezCurve[i+1]));
		}
	}
	bezpCurve.numpoint=numpoint*2;
	//copy(paramList.begin(),paramList.end(),bezpCurve.uList.begin());
	bezpCurve.uList.swap(paramList);
//	paramList.clear();
	m_bezStroke.push_back(bezpCurve);
}
Пример #5
0
/*
 *  ChordLengthParameterize :
 *  Assign parameter values to digitized points
 *  using relative distances between points.
 */
static double *ChordLengthParameterize(Point2 *d, int first, int last)
{
    int     i;
    double  *u;         /*  Parameterization        */

    u = (double *)malloc((unsigned)(last-first+1) * sizeof(double));

    u[0] = 0.0;
    for (i = first+1; i <= last; i++) {
        u[i-first] = u[i-first-1] +
                V2DistanceBetween2Points(&d[i], &d[i-1]);
    }

    for (i = first + 1; i <= last; i++) {
        u[i-first] = u[i-first] / u[last-first];
    }

    return(u);
}
Пример #6
0
/*
*  ChordLengthParameterize :
*	Assign parameter values to digitized points 
*	using relative distances between points.
*/
double *CBCStroke::ChordLengthParameterize(
											DISCURVE& d,			/* Array of digitized points */
											int		first,int last)		/*  Indices defining region	*/
{
	int		i;	
	double	*u;			/*  Parameterization		*/

	u = (double *)malloc((unsigned)(last-first+1) * sizeof(double));

	u[0] = 0.0;
	for (i = first+1; i <= last; i++) {
		u[i-first] = u[i-first-1] +
			V2DistanceBetween2Points(&d[i], &d[i-1]);
	}

	for (i = first + 1; i <= last; i++) {
		u[i-first] = u[i-first] / u[last-first];
	}

	return(u);
}
Пример #7
0
/*
 *  GenerateBezier :
 *  Use least-squares method to find Bezier control points for region.
 *
 */
static BezierCurve  GenerateBezier(Point2 *d, int first, int last, double *uPrime,
        Vector2 tHat1, Vector2 tHat2)
{
    int     i;
    Vector2     A[MAXPOINTS][2];    /* Precomputed rhs for eqn  */
    int     nPts;           /* Number of pts in sub-curve */
    double  C[2][2];            /* Matrix C     */
    double  X[2];           /* Matrix X         */
    double  det_C0_C1,      /* Determinants of matrices */
            det_C0_X,
            det_X_C1;
    double  alpha_l,        /* Alpha values, left and right */
            alpha_r;
    Vector2     tmp;            /* Utility variable     */
    BezierCurve bezCurve;   /* RETURN bezier curve ctl pts  */

    bezCurve = (Point2 *)malloc(4 * sizeof(Point2));
    nPts = last - first + 1;


    /* Compute the A's  */
    for (i = 0; i < nPts; i++) {
        Vector2     v1, v2;
        v1 = tHat1;
        v2 = tHat2;
        V2Scale(&v1, B1(uPrime[i]));
        V2Scale(&v2, B2(uPrime[i]));
        A[i][0] = v1;
        A[i][1] = v2;
    }

    /* Create the C and X matrices  */
    C[0][0] = 0.0;
    C[0][1] = 0.0;
    C[1][0] = 0.0;
    C[1][1] = 0.0;
    X[0]    = 0.0;
    X[1]    = 0.0;

    for (i = 0; i < nPts; i++) {
        C[0][0] += V2Dot(&A[i][0], &A[i][0]);
        C[0][1] += V2Dot(&A[i][0], &A[i][1]);
/*                  C[1][0] += V2Dot(&A[i][0], &A[i][1]);*/
        C[1][0] = C[0][1];
        C[1][1] += V2Dot(&A[i][1], &A[i][1]);

        tmp = V2SubII(d[first + i],
            V2AddII(
              V2ScaleIII(d[first], B0(uPrime[i])),
                V2AddII(
                    V2ScaleIII(d[first], B1(uPrime[i])),
                            V2AddII(
                            V2ScaleIII(d[last], B2(uPrime[i])),
                                V2ScaleIII(d[last], B3(uPrime[i]))))));


        X[0] += V2Dot(&A[i][0], &tmp);
        X[1] += V2Dot(&A[i][1], &tmp);
    }

    /* Compute the determinants of C and X  */
    det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1];
    det_C0_X  = C[0][0] * X[1]    - C[1][0] * X[0];
    det_X_C1  = X[0]    * C[1][1] - X[1]    * C[0][1];

    /* Finally, derive alpha values */
    alpha_l = (det_C0_C1 < ZERO_TOLERANCE) ? 0.0 : det_X_C1 / det_C0_C1;
    alpha_r = (det_C0_C1 < ZERO_TOLERANCE) ? 0.0 : det_C0_X / det_C0_C1;

    /* If alpha negative, use the Wu/Barsky heuristic (see text) */
    /* (if alpha is 0, you get coincident control points that lead to
     * divide by zero in any subsequent NewtonRaphsonRootFind() call. */
    double segLength = V2DistanceBetween2Points(&d[last], &d[first]);
    double epsilon = 1.0e-6 * segLength;
    if (alpha_l < epsilon || alpha_r < epsilon)
    {
        /* fall back on standard (probably inaccurate) formula, and subdivide further if needed. */
        double dist = segLength / 3.0;
        bezCurve[0] = d[first];
        bezCurve[3] = d[last];
        V2Add(&bezCurve[0], V2Scale(&tHat1, dist), &bezCurve[1]);
        V2Add(&bezCurve[3], V2Scale(&tHat2, dist), &bezCurve[2]);
        return (bezCurve);
    }

    /*  First and last control points of the Bezier curve are */
    /*  positioned exactly at the first and last data points */
    /*  Control points 1 and 2 are positioned an alpha distance out */
    /*  on the tangent vectors, left and right, respectively */
    bezCurve[0] = d[first];
    bezCurve[3] = d[last];
    V2Add(&bezCurve[0], V2Scale(&tHat1, alpha_l), &bezCurve[1]);
    V2Add(&bezCurve[3], V2Scale(&tHat2, alpha_r), &bezCurve[2]);
    return (bezCurve);
}
Пример #8
0
/*
 *  FitCubic :
 *      Fit a Bezier curve to a (sub)set of digitized points
 */
static void FitCubic(Point2 *d, int first, int last, Vector2 tHat1, Vector2 tHat2,
        double error, BezierContour &bezContour)
{
    BezierCurve bezCurve; /*Control points of fitted Bezier curve*/
    double  *u;     /*  Parameter values for point  */
    double  *uPrime;    /*  Improved parameter values */
    double  maxError;   /*  Maximum fitting error    */
    int     splitPoint; /*  Point to split point set at  */
    int     nPts;       /*  Number of points in subset  */
    double  iterationError; /*Error below which you try iterating  */
    int     maxIterations = 4; /*  Max times to try iterating  */
    Vector2 tHatCenter;     /* Unit tangent vector at splitPoint */
    int     i;

    iterationError = error * error;
    nPts = last - first + 1;

    /*  Use heuristic if region only has two points in it */
    if (nPts == 2) {
        double dist = V2DistanceBetween2Points(&d[last], &d[first]) / 3.0;

        bezCurve = (Point2 *)malloc(4 * sizeof(Point2));
        bezCurve[0] = d[first];
        bezCurve[3] = d[last];
        V2Add(&bezCurve[0], V2Scale(&tHat1, dist), &bezCurve[1]);
        V2Add(&bezCurve[3], V2Scale(&tHat2, dist), &bezCurve[2]);
        DrawBezierCurve(3, bezCurve, bezContour);
        free((void *)bezCurve);
        return;
    }

    /*  Parameterize points, and attempt to fit curve */
    u = ChordLengthParameterize(d, first, last);
    bezCurve = GenerateBezier(d, first, last, u, tHat1, tHat2);

    /*  Find max deviation of points to fitted curve */
    maxError = ComputeMaxError(d, first, last, bezCurve, u, &splitPoint);
    if (maxError < error) {
        DrawBezierCurve(3, bezCurve, bezContour);
        free((void *)u);
        free((void *)bezCurve);
        return;
    }


    /*  If error not too large, try some reparameterization  */
    /*  and iteration */
    if (maxError < iterationError) {
        for (i = 0; i < maxIterations; i++) {
            uPrime = Reparameterize(d, first, last, u, bezCurve);
            free((void *)bezCurve);
            bezCurve = GenerateBezier(d, first, last, uPrime, tHat1, tHat2);
            maxError = ComputeMaxError(d, first, last,
                       bezCurve, uPrime, &splitPoint);
            if (maxError < error) {
                DrawBezierCurve(3, bezCurve, bezContour);
                free((void *)u);
                free((void *)bezCurve);
                free((void *)uPrime);
                return;
            }
        free((void *)u);
        u = uPrime;
        }
    }

    /* Fitting failed -- split at max error point and fit recursively */
    free((void *)u);
    free((void *)bezCurve);
    tHatCenter = ComputeCenterTangent(d, splitPoint);
    FitCubic(d, first, splitPoint, tHat1, tHatCenter, error, bezContour);
    V2Negate(&tHatCenter);
    FitCubic(d, splitPoint, last, tHatCenter, tHat2, error, bezContour);
}
Пример #9
0
/*
 *  GenerateBezier :
 *  Use least-squares method to find Bezier control points for region.
 *
 */
static BezierCurve  GenerateBezier(
    Point2	*d,			/*  Array of digitized points	*/
    int		first, int last,		/*  Indices defining region	*/
    double	*uPrime,		/*  Parameter values for region */
    Vector2	tHat1, Vector2 tHat2)	/*  Unit tangents at endpoints	*/
{
    int 	i;
//    Vector2 	A[MAXPOINTS][2];	/* Precomputed rhs for eqn	*/
    int 	nPts;			/* Number of pts in sub-curve */
    double 	C[2][2];			/* Matrix C		*/
    double 	X[2];			/* Matrix X			*/
    double 	det_C0_C1,		/* Determinants of matrices	*/
    	   	det_C0_X,
	   		det_X_C1;
    double 	alpha_l,		/* Alpha values, left and right	*/
    	   	alpha_r;
    Vector2 	tmp;			/* Utility variable		*/
    BezierCurve	bezCurve;	/* RETURN bezier curve ctl pts	*/

    bezCurve = (Point2 *)malloc(4 * sizeof(Point2));
    nPts = last - first + 1;

    Vector2 (*A)[2];
	 
	 A = new Vector2[nPts][2];	/* Precomputed rhs for eqn	*/
 
    /* Compute the A's	*/
    for (i = 0; i < nPts; i++) {
		Vector2		v1, v2;
		v1 = tHat1;
		v2 = tHat2;
		V2Scale(&v1, B1(uPrime[i]));
		V2Scale(&v2, B2(uPrime[i]));
		A[i][0] = v1;
		A[i][1] = v2;
    }

    /* Create the C and X matrices	*/
    C[0][0] = 0.0;
    C[0][1] = 0.0;
    C[1][0] = 0.0;
    C[1][1] = 0.0;
    X[0]    = 0.0;
    X[1]    = 0.0;

    for (i = 0; i < nPts; i++) {
        C[0][0] += V2Dot(&A[i][0], &A[i][0]);
		C[0][1] += V2Dot(&A[i][0], &A[i][1]);
/*					C[1][0] += V2Dot(&A[i][0], &A[i][1]);*/	
		C[1][0] = C[0][1];
		C[1][1] += V2Dot(&A[i][1], &A[i][1]);

		tmp = V2SubII(d[first + i],
	        V2AddII(
	          V2ScaleIII(d[first], B0(uPrime[i])),
		    	V2AddII(
		      		V2ScaleIII(d[first], B1(uPrime[i])),
		        			V2AddII(
	                  		V2ScaleIII(d[last], B2(uPrime[i])),
	                    		V2ScaleIII(d[last], B3(uPrime[i]))))));
	

	X[0] += V2Dot(&A[i][0], &tmp);
	X[1] += V2Dot(&A[i][1], &tmp);
    }

    /* Compute the determinants of C and X	*/
    det_C0_C1 = C[0][0] * C[1][1] - C[1][0] * C[0][1];
    det_C0_X  = C[0][0] * X[1]    - C[0][1] * X[0];
    det_X_C1  = X[0]    * C[1][1] - X[1]    * C[0][1];

    /* Finally, derive alpha values	*/
    if (det_C0_C1 == 0.0) {
		det_C0_C1 = (C[0][0] * C[1][1]) * 10e-12;
    }
    alpha_l = det_X_C1 / det_C0_C1;
    alpha_r = det_C0_X / det_C0_C1;


    /*  If alpha negative, use the Wu/Barsky heuristic (see text) */
    if (alpha_l < 0.0 || alpha_r < 0.0) {
		double	dist = V2DistanceBetween2Points(&d[last], &d[first]) /
					3.0;

		bezCurve[0] = d[first];
		bezCurve[3] = d[last];
		V2Add(&bezCurve[0], V2Scale(&tHat1, dist), &bezCurve[1]);
		V2Add(&bezCurve[3], V2Scale(&tHat2, dist), &bezCurve[2]);

		delete[] A;

		return (bezCurve);
    }

    /*  First and last control points of the Bezier curve are */
    /*  positioned exactly at the first and last data points */
    /*  Control points 1 and 2 are positioned an alpha distance out */
    /*  on the tangent vectors, left and right, respectively */
    bezCurve[0] = d[first];
    bezCurve[3] = d[last];
    V2Add(&bezCurve[0], V2Scale(&tHat1, alpha_l), &bezCurve[1]);
    V2Add(&bezCurve[3], V2Scale(&tHat2, alpha_r), &bezCurve[2]);

	 delete[] A;

    return (bezCurve);
}
Пример #10
0
void CBCStroke::DrawHarryBrush(FCObjImage& img,BezierPressCurve& bezpCurve,BYTE alpha,float zoom)
{
	double t,delt;
	t=0.0;
	int x1,y1,x2,y2;
	x1=y1=x2=y2=0;
	for(int i=0;i<=bezpCurve.degree;++i){
		bezpCurve.bezCurve[i].x=zoom*(bezpCurve.bezCurve[i].x);
		bezpCurve.bezCurve[i].y=zoom*(bezpCurve.bezCurve[i].y);
	}
	float numpoint=0;
	if(bezpCurve.degree>=2){
		numpoint=V2DistanceBetween2Points(&(bezpCurve.bezCurve[0]),&(bezpCurve.bezCurve[1]));
		for (int i =1; i <bezpCurve.degree; i++) {
			numpoint+=V2DistanceBetween2Points(&(bezpCurve.bezCurve[i]),&(bezpCurve.bezCurve[i+1]));
		}
	}
	numpoint=numpoint*2;
	if(numpoint<=0)
		return;
	delt=(double)1/numpoint;
	bezpCurve.numpoint=0;
	int count=0;
	TPosition tp[3];
	std::vector<TPosition> pList;
	for(int i=0;i<=numpoint;++i){				
		Point2 p=CBCStroke::BezierII(bezpCurve.degree,bezpCurve.bezCurve,t);
		x1=p.x;
		y1=p.y;
		if(x1!=x2||y1!=y2){
			PARAMER param;
			//CStrokeTransform::GenParamer(bezpCurve.uList,t,param);
			TPosition position;
			
			position.press=(param.press<1)?1:param.press;
			position.m_angle_z=param.m_angle_z;
			position.m_angle_xy=param.m_angle_xy;
			position.m_x=x1;
			position.m_y=y1;
			//m_disCurve.
			pList.push_back(position);
			//m_lpPaper->DrawSection(img,position,alpha);
			x2=x1;
			y2=y1;
			bezpCurve.numpoint++;
		}	
		t+=delt;
	}
	int size=pList.size();
	if(size<=3)
		return;
	std::vector<TPosition> pList2;
	int i=0;
	for(;i<size/2-1;++i)
	{
		pList2.push_back(pList[2*i]);
	}
	pList2.push_back(pList[size-1]);

	Vector2 v,v_cur,v_pre;
	v.x=pList2[1].m_x-pList2[0].m_x;
	v.y=pList2[1].m_y-pList2[0].m_y;
	V2MakePerpendicular(&v,&v_pre);
	int j=0;
	for(j=2;j<pList2.size();++j)
	{
		Point2 A,B,C;
		A.x=pList[j-2].m_x;
		A.y=pList[j-2].m_y;
		B.x=pList[j-1].m_x;
		B.y=pList[j-1].m_y;
		C.x=pList[j].m_x;
		C.y=pList[j].m_y;
		v_cur=AngleBisectors(A,B,C);
		m_lpPaper->DrawSection(img,pList2[j-2],v_pre,pList2[j-1],v_cur,alpha);
		v_pre=v_cur;
	}
	if(i<=2)
		return;
	v.x=pList2[j-1].m_x-pList2[j-2].m_x;
	v.y=pList2[j-1].m_y-pList2[j-2].m_y;
	V2MakePerpendicular(&v,&v_cur);
	m_lpPaper->DrawSection(img,pList2[j-2],v_pre,pList2[j-1],v_cur,alpha);
}