コード例 #1
0
ファイル: BCStroke.cpp プロジェクト: lupnfer/camc
void CBCStroke::Draw(CDC* pDC)
{
	BEZIERSTROKE::iterator it;
	for(it=m_bezStroke.begin();it!=m_bezStroke.end();++it){
		DrawBezierCurve(pDC,*it);
	}
}
コード例 #2
0
ファイル: BCStroke.cpp プロジェクト: lupnfer/camc
//********************************************************************************************************
void CBCStroke::Draw(FCObjImage& img,BYTE alpha,float zoompaper,float zoompress)
{
	//m_vb.BeginOneStrokeDraw(img.GetPaper());
	BEZIERSTROKE::iterator it;
	int w=img.Width();
	int h=img.Height();
	img.Stretch(w*3,h*3);
	for(it=m_bezStroke.begin();it!=m_bezStroke.end();++it){
		DrawBezierCurve(img,*it,alpha,zoompaper*3,zoompress*3);
	}
	img.AntiAliased_Zoom(3);
	//m_vb.EndOneStrokeDraw(img.GetPaper());
}
コード例 #3
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);
}
コード例 #4
0
ファイル: UICurveEditor.cpp プロジェクト: Mateuus/devsrc
void UICurveEditor::DrawBezier(	float in_x, float in_y, float in_w, float in_h, const char *Title, r3dBezierGradient* edit_val, float* pVertScale,
						   float in_minVal, float in_maxVal, int x_steps /*= 10*/, int y_steps /*= 10*/,
						   int x_precision /*= 2*/, int y_precision /*= 2*/, bool bUseDesktop )
{
	if ( bUseDesktop )
	{
		if ( ! Desktop().IsWindowVisible( in_x, in_y, in_x + in_w, in_y + in_h ) )
			return;
		in_x -= Desktop().GetX();
		in_y -= Desktop().GetY();
	}


	const int   x_dels    = x_steps;
	const int   y_dels    = y_steps;

	static const float off_field  = 30;
	static const float off_header = 20;

	static const r3dColor clr_bg(50, 50, 50);
	static const r3dColor clr_hdr(80, 120, 80);
	static const r3dColor clr_fld(30, 30, 30);
	static const r3dColor clr_line(100, 100, 100);
	static const r3dColor clr_selline(200, 200, 200);

	float ui_x = in_x;
	float ui_y = in_y;
	float ui_w = in_w;
	float ui_h = in_h - 8;

	// field coords
	fx = ui_x + off_field; 
	fw = ui_w - off_field - off_field; 
	fy = ui_y + off_header; 
	fh = ui_h - off_field - off_header;

	r3dBezierGradient& grad = *edit_val;

	if( pVertScale )
	{
		r3d_assert( "Copy me from UICurveEditor::DrawIM!!" );
	}
	else
	{
		vertScale = 1.f ;
	}

	if(in_minVal > -9999) {
		minMaxLocked = true;
		minVal = in_minVal;
		maxVal = in_maxVal;

		// apply min/max limits
		float min = R3D_MIN(minVal, maxVal);
		float max = R3D_MAX(minVal, maxVal);
		for(int i=0; i<grad.NumValues; i++) {
			r3dBezierGradient::val_s& gv = grad.Values[i];

			gv.val[0] = R3D_CLAMP(gv.val[0], min, max);
		}
	} else { 
		minMaxLocked = false;

		// unrestricted mode - detect min/max
		minVal = 9999;
		maxVal = -9999;
		for(int i=0; i<grad.NumValues; i++) {
			r3dBezierGradient::val_s& gv = grad.Values[i];

			if(minVal > gv.val[0]) minVal = gv.val[0];
			if(maxVal < gv.val[0]) maxVal = gv.val[0];
		}
		minVal -= 1.0f;
		maxVal += 1.0f;

		if(imgui_val == edit_val) {
			// do not change min/val while dragging!
			minVal = dragSavedMin;
			maxVal = dragSavedMax;
		}
	}

	// draw backgoround
	r3dDrawBox2D(ui_x, ui_y, ui_w, in_h, clr_bg);
	r3dDrawBox2D(fx, fy, fw, fh, clr_fld);
	r3dDrawBox2D(ui_x, ui_y, ui_w, off_header-2, clr_hdr);

	MenuFont_Editor->PrintF(ui_x+5, ui_y+2, r3dColor(255,255,255), Title);

	x_precision = R3D_MIN( R3D_MAX( x_precision, 0 ), 9 );
	y_precision = R3D_MIN( R3D_MAX( y_precision, 0 ), 9 );

	char num_fmt[] = "%.0f";
	const int fmt_precision_pos = 2;

	// draw x lines - from 0.0 to 1.0
	{
		float x  = fx;
		float y  = fy;
		float dx = fw / x_dels;

		num_fmt[fmt_precision_pos] = '0' + x_precision;

		for(int i=0; i<=x_dels; i++) {
			r3dDrawVLine(x, y, ui_h - off_header, clr_line);
			MenuFont_Editor->PrintF(x+2, y+fh+2, r3dColor::white, num_fmt, float(i) / x_dels);
			x += dx;
		}
	}

	// draw y lines - from minVal to maxVal
	{
		float x   = float(ui_x);
		float y   = fy;
		float dy  = fh / y_dels;
		float val = maxVal;
		float vd  = (minVal - maxVal) / y_dels;

		num_fmt[fmt_precision_pos] = '0' + y_precision;

		for(int i=0; i<=y_dels; i++) {
			r3dDrawHLine(x, y, ui_w, clr_line);
			MenuFont_Editor->PrintF(x, y, r3dColor::white, num_fmt, val);
			y += dy;
			val += vd;
		}
	}

	DrawBezierCurve(*edit_val );
	DrawBezierPoints(*edit_val, imgui_val == NULL);

	if(imgui_disabled)
		return;
	if(imgui_val && imgui_val != edit_val)
		return;

	// draw mouseover lines && current coordinate/value
	if(!g_imgui_InDrag && imgui_mx >= fx && imgui_mx <= fx+fw && imgui_my >= fy && imgui_my <= fy+fh && (imgui_val == NULL || imgui_val == edit_val)) {
		r3dDrawHLine(fx, imgui_my, fw, clr_selline);
		r3dDrawVLine(imgui_mx, fy, fh, clr_selline);

		if(selectedPnt == -1) {
			float vx, vy;
			CalcFromCoord(imgui_mx, imgui_my, vx, vy);
			MenuFont_Editor->PrintF(imgui_mx+2, imgui_my+2, r3dColor::white, "----Time:%.2f Val:%.4f", vx, vy);
		}
	}

	// if we snapped on point - print it's coordinate/value
	if(selectedPnt != -1) {
		const r3dBezierGradient::val_s& gv = grad.Values[selectedPnt];
		float x, y;
		CalcFromValue(gv, x, y);

		MenuFont_Editor->PrintF(x+2, y+2, r3dColor::white, "****Time:%.2f Val:%.4f", gv.time, gv.val[0]);
		MenuFont_Editor->PrintF(ui_x+0, ui_y-2, r3dColor::white, "[%.2f]:%.4f", gv.time, gv.val[0]);
	}

	bool act1 = !g_imgui_InDrag && imgui_lbp && !Keyboard->IsPressed(kbsLeftControl);
	bool act2 = !g_imgui_InDrag && imgui_lbp && Keyboard->IsPressed(kbsLeftControl);

	// 
	// point dragging
	//
	if(imgui_val == NULL && selectedPnt != -1 && imgui_val != this && act1) {
		// enable point dragging
		imgui_val   = edit_val;
		draggingPnt = selectedPnt;
		dragSavedMin= minVal;
		dragSavedMax= maxVal;
	}

	if(imgui_val == edit_val) {
		assert(draggingPnt != -1);
		// update dragging point
		float vx, vy;
		CalcFromCoord(imgui_mx, imgui_my, vx, vy);

		r3dBezierGradient::val_s& gv = grad.Values[draggingPnt];
		if(gv.time < 0.001f || gv.time > 0.999f) {
			// do not edit value for border params
			gv.val[0] = vy;  
		} else {
			gv.time   = R3D_CLAMP(vx, 0.01f, 0.98f);
			gv.val[0] = vy;

			grad.ResortAfterChange(&selectedPnt);
		}

		if(imgui_lbr) {
			imgui_val   = NULL;
			draggingPnt = -1;
		}

		return;
	}

	//
	// point adding/removing
	//
	if(imgui_mx >= fx && imgui_mx <= fx+fw && imgui_my >= fy && imgui_my <= fy+fh) 
	{
		assert(imgui_val == NULL);

		if(selectedPnt != -1 && act2) {
			// remove selected point (only not border ones)
			if(selectedPnt != 0 && selectedPnt != grad.NumValues-1) {

				grad.NumValues--;
				memmove(&grad.Values[selectedPnt], &grad.Values[selectedPnt+1], sizeof(grad.Values[0]) * (grad.NumValues - selectedPnt));

				grad.UpdateControlPoints ();
				selectedPnt = -1;
				return;
			}
		}

		if(selectedPnt == -1 && act1) {
			// add new control point and lock it for dragging
			float vx, vy;
			CalcFromCoord(imgui_mx, imgui_my, vx, vy);

			draggingPnt = grad.AddValue(vx, vy);
			dragSavedMin= minVal;
			dragSavedMax= maxVal;
			imgui_val   = edit_val;
			return;
		}
	}

	return;
}