Inkscape's bezmisc.py improvements English version

cnc-club.ru for English speaking users
Аватара пользователя
Nick
Мастер
Сообщения: 22609
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1630
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Inkscape's bezmisc.py improvements English version

Сообщение Nick »

While developing Gcode tools extension found that bezmisc.py needs some improvements:

1. bezierparameterize function
This corrections have effect if one or more tangents are zeros.
If one tangent equals 0 Bezier's cubic path becomes Bezier quadratic path if both tangents are zeros it will become a straight line. Without this correction bezierslopeatt will give a 0 near the end with 0 tangent.

Код: Выделить всё

def bezierparameterize(((bx0,by0),(bx1,by1),(bx2,by2),(bx3,by3))):
	#parametric bezier
	ax,ay,bx,by,cx,cy,x0,y0 = 0, 0, 0, 0, 0, 0, 0, 0 
	if (bx0,by0)==(bx1,by1) and (bx2,by2)==(bx3,by3):
		x0=bx0
		cx=bx3-bx0
		y0=by0
		cy=by3-by0
	elif (bx2,by2)==(bx3,by3) :
	    x0=bx0
	    cx = (bx1-bx0)*2
	    bx = bx0-2*bx1+bx2
	    y0=by0
	    cy = (by1-by0)*2
	    by = by0-2*by1+by2
	elif (bx0,by0)==(bx1,by1) :
	    x0=bx1
	    cx = (bx2-bx1)*2
	    bx = bx1-2*bx2+bx3
	    y0=by1
	    cy = (by2-by1)*2
	    by = by1-2*by2+by3
	else:
		x0=bx0
		y0=by0
		cx=3*(bx1-x0)
		bx=3*(bx2-bx1)-cx
		ax=bx3-x0-cx-bx
		cy=3*(by1-y0)
		by=3*(by2-by1)-cy
		ay=by3-y0-cy-by
	return ax,ay,bx,by,cx,cy,x0,y0
bezmisc.bezierparameterize = bezierparameterize
2. Here's remade linebezierintersect to csp_line_intersection wit a cubic solver
It's not exact line and bezier intersect but line and cubic super path, which are in fact almost the same. And additional cubic solver.

Код: Выделить всё

def cubic_solver(a,b,c,d):	
	if a!=0:
		#	Monics formula see http://en.wikipedia.org/wiki/Cubic_function#Monic_formula_of_roots
		a,b,c = (b/a, c/a, d/a)
		m = 2*a**3 - 9*a*b + 27*c
		k = a**2 - 3*b
		n = m**2 - 4*k**3
		w1 = -.5 + .5*cmath.sqrt(3)*1j
		w2 = -.5 - .5*cmath.sqrt(3)*1j
		m1 = pow(complex((m+cmath.sqrt(n))/2),1./3)
		n1 = pow(complex((m-cmath.sqrt(n))/2),1./3)
		x1 = -1./3 * (a + m1 + n1)
		x2 = -1./3 * (a + w1*m1 + w2*n1)
		x3 = -1./3 * (a + w2*m1 + w1*n1)
		return [x1,x2,x3]
	elif b!=0:
		det = c**2-4*b*d
		if det>0 :
			return [(-c+math.sqrt(det))/(2*b),(-c-math.sqrt(det))/(2*b)]
		elif d == 0 :
			return [-c/(b*b)] 	
		else :
			return [(-c+cmath.sqrt(det))/(2*b),(-c-cmath.sqrt(det))/(2*b)]
	elif c!=0 :
		return [-d/c]
	else : return []

def csp_line_intersection(l1,l2,sp1,sp2):
	dd=l1[0]
	cc=l2[0]-l1[0]
	bb=l1[1]
	aa=l2[1]-l1[1]
	if aa==cc==0 : return []
	if aa:
		coef1=cc/aa
		coef2=1
	else:
		coef1=1
		coef2=aa/cc
	bez = (sp1[1][:],sp1[2][:],sp2[0][:],sp2[1][:])
	ax,ay,bx,by,cx,cy,x0,y0=bezmisc.bezierparameterize(bez)
	a=coef1*ay-coef2*ax
	b=coef1*by-coef2*bx
	c=coef1*cy-coef2*cx
	d=coef1*(y0-bb)-coef2*(x0-dd)
	roots = cubic_solver(a,b,c,d)
	retval = []
	for i in roots :
		if type(i) is complex and i.imag==0:
			i = i.real
		if type(i) is not complex and 0<=i<=1:
			retval.append(i)
	return retval
alfcnc
Кандидат
Сообщения: 98
Зарегистрирован: 02 апр 2010, 19:10
Репутация: 0
Заслуга: Tester
Контактная информация:

Re: Inkscape's bezmisc.py improvements English version

Сообщение alfcnc »

Ok ! very nice.
Have you had this to inkscape ?
Or we must had it manually ?
Аватара пользователя
Nick
Мастер
Сообщения: 22609
Зарегистрирован: 23 ноя 2009, 16:45
Репутация: 1630
Заслуга: Developer
Откуда: Gatchina, Saint-Petersburg distr., Russia
Контактная информация:

Re: Inkscape's bezmisc.py improvements English version

Сообщение Nick »

Yes I've posted it on launchpad where inkscape being developed. And it appears that I was wrong thinking that if two control points of cubic bezier path are the same then the path becomes a quadratic bezier path. So we have to think it over. But cubic solver is ok and I hope to see it next inkscape version.

I think that these improvements will be included into gcode tools for long time because there will be a lot of people who use inkscape older than 0.48.

The changes I've made to bezmisc.py was needed to illiminate problem with slopes. If one or two control points of the path are the same the slope of at the end of the segment becomes (dx, dy) = (0, 0) and this is the problem, because we need to know dx/dy. So as I was wrong with that we have to think it over how to get dx/dy if the slope dx(t)=0 and dy(t)=0.
Ответить

Вернуться в «English forum»