
    BPc<                         d Z ddlZddlZddlZddlmZ ddlmZ d Z	d$dZ
d%d
Zd Zd Zd$dZd&dZd'dZd Zd Zd Zd Zd Zd Zd Zd Zd'dZd Zd Zd(dZd&dZd Zd  Zd)d!Z d" Z!d# Z"dS )*z
Bezier calculations
    N   )DirectedLineSegment)inkex_gettextc                 x    t          j        |d         | d         z
  dz  |d         | d         z
  dz  z             S )z-The straight line distance between two pointsr      r   mathsqrt)point_apoint_bs     ./usr/share/inkscape/extensions/inkex/bezier.pypointdistancer   %   sB    9
!*wqz
!a	'WQZ'!*-D,JK            ?c                 v    | d         ||d         | d         z
  z  z   | d         ||d         | d         z
  z  z   fS )z-Returns the point between point a and point br   r    )r   r   times      r   between_pointr   ,   sM    1:
WQZ 788'!*t
WQZH ;  r         I@c                 *    t          | ||dz            S )z:Returns between_point but takes percent instead of 0.0-1.0g      Y@)r   )r   r   percents      r   percent_pointr   3   s    '7U?;;;r   c                    | r|| z  || z  || z  }}}d|dz  z  d|z  |z  z
  d|z  z   }|dz  d|z  z
  }|dz  d|dz  z  z
  }	dd	t          j        d
          z  z   }
dd	t          j        d
          z  z
  }|	dk     rkt          t          |t          j        |	          z   dz            d          }t          t          |t          j        |	          z
  dz            d          }n|t	          j        |	          z   dk     r+t          |t	          j        |	          z    dz  d           }n(t          |t	          j        |	          z   dz  d          }|t	          j        |	          z
  dk     r+t          |t	          j        |	          z
   dz  d           }n(t          |t	          j        |	          z
  dz  d          }d||z   |z   z  d||
|z  z   ||z  z   z  d|||z  z   |
|z  z   z  fS |rV|dz  d|z  |z  z
  }|r<| t          j        |          z   d|z  z  | t          j        |          z
  d|z  z  fS | d|z  z  fS |r
d| |z  z  fS dS )z;Get the Cubic function, moic formular of roots, simple root       @   g      "@g      ;@r   g      @      @g      r   g      r   gUUUUUU?gUUUUUUտ      ?r   )cmathr
   powcomplexr	   )root_aroot_broot_croot_dmono_amono_bmono_cmknw1w2m1n1dets                  r   root_wrapperr0   8   s    
 #)6/6F?FVO&!)OcFlV33dVmCAIf$qD3A:C%*T****C%*T****q55Wa%*Q--/1455w??BWa%*Q--/1455w??BB49Q<<!##A	!,-17;;;!dill*a/9949Q<<!##A	!,-17;;;!dill*a/99b()b(2723b(2723
 	

  +ckC&L611 	5:c??*sV|<5:c??*sV|<  3<(** +w'(**2r   c                     t          | d         | d                   t          | d         |d                   z   t          |d         |d                   z   S )z0Return the aproximate length between two beziersr   r   r   )r   )sp1sp2s     r   bezlenapprxr4   a   sR     	c!fc!f%%
AA
'
'	(
AA
'
'	(r   c                    t          | d         | d         |          }t          | d         |d         |          }t          |d         |d         |          }t          |||          }t          |||          }t          |||          }| d         dd         | d         dd         |g|||g||d         dd         |d         dd         ggS )z'Split a cubic bezier at the time periodr   r   r   Ntpoint)	r2   r3   r   r-   m2m3m4m5r(   s	            r   cspbezsplitr<   j   s    	AA	%	%B	AA	%	%B	AA	%	%B	B		B	B		Br2tAVAAAYAqqq	2&Qb#a&)SVAAAY5OPPr   MbP?c                     | d         dd         | d         dd         |d         dd         |d         dd         f}t          |||          }t          | ||          S )zSplit a cubic bezier at lengthr   Nr   r   )beziertatlengthr<   )r2   r3   length	tolerancebezr   s         r   cspbezsplitatlengthrC   u   sc    q6!!!9c!fQQQiQCF111I
6C3	22DsC&&&r   c                     | d         dd         | d         dd         |d         dd         |d         dd         f}t          ||          S )zGet cubic bezier segment lengthr   Nr   r   )bezierlength)r2   r3   rA   rB   s       r   cspseglengthrF   |   sP    q6!!!9c!fQQQiQCF111I
6CY'''r   c                    d}g }| D ]v}|                     g            t          dt          |                    D ]A}t          ||dz
           ||                   }|d                              |           ||z  }Bw||fS )zGet cubic bezier lengthr   r   )appendrangelenrF   )csptotallengthsspils         r   	csplengthrR      s    EG  rq#b''"" 	 	ARAY1..ABKq!!!QJEE	 E>r   c                     | \  \  }}\  }}\  }}\  }}|}	|}
d||	z
  z  }d||z
  z  |z
  }||	z
  |z
  |z
  }d||
z
  z  }d||z
  z  |z
  }||
z
  |z
  |z
  }|||||||	|
fS )us  Return the bezier parameter size
    Converts the bezier parametrisation from the default form
    P(t) = (1-t)³ P_1 + 3(1-t)²t P_2 + 3(1-t)t² P_3 + t³ x_4
    to the a form which can be differentiated more easily
    P(t) = a t³ + b t² + c t + P0

    Args:
        bez (List[Tuple[float, float]]): the Bezier curve. The elements of the list the
            coordinates of the points (in this order): Start point, Start control point,
            End control point, End point.

    Returns:
        Tuple[float, float, float, float, float, float, float, float]:
            the values ax, ay, bx, by, cx, cy, x0, y0
    r   r   )rB   bx0by0bx1by1bx2by2bx3by3x0y0cxbxaxcybyays                    r   bezierparameterizerd      s      8;4Zc3#sZc3#s	B	B	
cBhB	
cCi2	B	rB	B	
cBhB	
cCi2	B	rB	Br2r2r2r))r   c                    | \  \  }}\  }}|}||z
  }|}||z
  }	|	r||	z  }
d}nd}
|	|z  }t          |          \  }}}}}}}}|
|z  ||z  z
  }|
|z  ||z  z
  }|
|z  ||z  z
  }|
||z
  z  |||z
  z  z
  }t          ||||          }g }|D ]q}t          |t                    r|j        dk    r|j        }t          |t                    s3d|cxk    rdk    r&n N|                    t          ||                     r|S )z!Where a line and bezier intersectr   r   )rd   r0   
isinstancer    imagrealrI   bezierpointatt)arg_arB   lx1ly1lx2ly2ddccbbaacoef1coef2r`   rc   r_   rb   r^   ra   r\   r]   abcdrootsretvalrP   s                              r   linebezierintersectr{      s\   $Zc3#s	B	sB	B	sB	 RR%7%<%<"BBBB
URZA
URZA
URZAbER"W--AAq!$$EF 2 2a!! 	afkkA!W%% 	2!q++++A+++++MM.a00111Mr   c                     t          |           \  }}}}}}}}	||dz  z  ||dz  z  z   ||z  z   |z   }
||dz  z  ||dz  z  z   ||z  z   |	z   }|
|fS )z7Get coords at the given time point along a bezier curver   r   rd   )rB   tr`   rc   r_   rb   r^   ra   r\   r]   xys               r   ri   ri      sy    %7%<%<"BBBB
adbAqDk!BF*R/A
adbAqDk!BF*R/Aa4Kr   c                     t          |           \  }}}}}}}}d|z  |dz  z  d|z  |z  z   |z   }	d|z  |dz  z  d|z  |z  z   |z   }
|	|
fS )aV  Get slope at the given time point along a bezier curve
        The slope is computed as (dx, dy) where dx = df_x(t)/dt and dy = df_y(t)/dt.
        Note that for lines P1=P2 and P3=P4, so the slope at the end points is dx=dy=0
        (slope not defined).

    Args:
        bez (List[Tuple[float, float]]): the Bezier curve. The elements of the list the
            coordinates of the points (in this order): Start point, Start control point,
            End control point, End point.
        t (float): time in the interval [0, 1]

    Returns:
        Tuple[float, float]: x and y increment
    r   r   r}   )rB   r~   r`   rc   r_   rb   r^   ra   _dxdys              r   bezierslopeattr      sq     $6c#:#: BBBAq	
R1a41r6A:	%	*B	
R1a41r6A:	%	*Br6Mr   c                    t          |           \  }}}}}}}}|\  }	}
|
r-d|	|
z  z  }d|z  d|z  |z  z
  }d|z  d|z  |z  z
  }|||z  z
  }n1|	r-d|
|	z  z  }d|z  d|z  |z  z
  }d|z  d|z  |z  z
  }|||z  z
  }ng S t          d|||          }g }|D ]c}t          |t                    r|j        dk    r|j        }t          |t                    s%d|cxk    rdk    rn N|                    |           d|S )z1Reverse; get time from slope along a bezier curver   r   r   r   r   )rd   r0   rf   r    rg   rh   rI   )rB   rx   r`   rc   r_   rb   r^   ra   r   r   r   sloperu   rv   rw   ry   rz   rP   s                     r   beziertatsloper      sZ   #5c#:#: BBBAqHR	 rBwFQVe^#FQVe^#eO	 rBwFQVe^#FQVe^#eO	Aq!$$EF  a!! 	afkkA!W%% 	!q++++A+++++MM!Mr   c                 B    | \  }}|\  }}||||z
  z  z   ||||z
  z  z   fS )a4  Linearly interpolate between p1 and p2.

    t = 0.0 returns p1, t = 1.0 returns p2.

    :return: Interpolated point
    :rtype: tuple

    :param p1: First point as sequence of two floats
    :param p2: Second point as sequence of two floats
    :param t: Number between 0.0 and 1.0
    :type t: float
    r   )p1p2r~   x1y1x2y2s          r   r7   r7     s;     FBFBR"WrAbM111r   c                 ,   | \  \  }}\  }}\  }}\  }}	t          ||f||f|          }
t          ||f||f|          }t          ||f||	f|          }t          |
||          }t          |||          }t          |||          }||f|
||f|||||	fffS )zSplit bezier at given timer6   )rB   r~   rT   rU   rV   rW   rX   rY   rZ   r[   r-   r8   r9   r:   r;   r(   s                   r   beziersplitattr     s    7:4Zc3#sZc3#s	c
S#J	*	*B	c
S#J	*	*B	c
S#J	*	*B	B		B	B		Br2qA#JB"QBc
$;;;r   c                 ^   d}t          dd          D ]$}|t          | |dz
           | |                   z  }%t          | d         | d                   }||z
  |k    r7t          | d          \  }}t          |||           t          |||           dS |dxx         |dz  |dz  z   z  cc<   dS )zAGravesen, Add if the line is closed, in-place addition to array lr   r      r   r   r   N)rJ   r   r   
addifclose)rB   rQ   errorboxrP   chordfirstseconds           r   r   r   &  s    
C1a[[ 1 1}SQZQ000#a&#a&))Eeu&sC00v5!U###61e$$$$$	!sus{++r   c                     |\  }}}}}}|| dz  z  || z  z   |z   dz  || dz  z  || z  z   |z   dz  z   }t          j        |          S )zBezier Arc Length Functionr   r   )	r~   argsr`   r_   r^   rc   rb   ra   rz   s	            r   balfr   7  sd    !BBBAqDkBF"R'A-q!trAv1E1Jq0PPF9Vr   c                    d}|| z
  dz  }t          | |          t          ||          z   }|| z
  dz  }d}	t          | |z   |          }
||d|	z  z   d|
z  z   z  }d|z  }||k     rt          ||z
            |k    rr|dz  }|dz  }|dz  }|	|
z  }	d}
|}t          d|d          D ],}|
t          | ||z  z   |          z  }
||d|	z  z   d|
z  z   z  }-||k     rt          ||z
            |k    r|S )aQ  Calculate the length of a bezier curve using Simpson's algorithm:
    http://steve.hollasch.net/cgindex/curves/cbezarclen.html

    Args:
        start (int): Start time (between 0 and 1)
        end (int): End time (between start time and 1)
        maxiter (int): Maximum number of iterations. If not a power of 2, the algorithm
        will behave like the value is set to the next power of 2.
        tolerance (float):  maximum error ratio
        bezier_args (list): arguments as computed by bezierparametrize()

    Returns:
        float: the appoximate length of the bezier curve
    r   g      @r           r   r   )r   absrJ   )startendmaxiterrA   bezier_argsr*   
multiplierendsumintervalasumbsumest1est0rP   s                 r   simpsonr   >  sM     	
A+$J%%%S+(>(>>Fes"HD +..D3:.#*=>D:D
g++#dTk**Y66	Qc
Cq!Q 	G 	GAD!h,/===D3:!6#*!EFDD g++#dTk**Y66 Kr   r   c                 |    t          |           \  }}}}}}}	}	t          d|d|d|z  d|z  |d|z  d|z  |g          S )zGet length of bezier curver   i   r   r   )rd   r   )
rB   rA   r   r`   rc   r_   rb   r^   ra   r   s
             r   rE   rE   e  sU    #5c#:#: BBBAq3dIBBAFAPRFTV/WXXXr   c                     t          | |d          }d}|}||z  }||z
  }t          |          |k    r?|dz  }|dk     r||z  }n||z  }t          | ||          }||z
  }t          |          |k    ?|S )z-Get bezier curve time at the length specifiedr   r   r   )rE   r   )rB   rQ   rA   curlenr   tdiv	targetlendiffs           r   r?   r?   k  s    #y#..FDDF
IID
d))i

!88DLDDDLDc9d33	! d))i

 Kr   c                     t          | d         | d                   }t           |j        | d           |j        | d                    S )z(Get maximum distance within bezier curver   r   r   r   )r   maxdistance_to_point)rB   segs     r   maxdistr   }  sG    
c!fc!f
-
-C$s$c!f-/Ds/Dc!f/MNNNr   c                 0    | D ]}t          ||           dS )zSub-divide cubic sub-pathsN)subdiv)rL   flatrO   s      r   	cspsubdivr     s.      r4 r   c                    |t          |           k     r| |dz
           d         }| |dz
           d         }| |         d         }| |         d         }||||f}t          |          }||k    r|dz  }nWt          |d          \  }	}
|	d         | |dz
           d<   |
d         | |         d<   |	d         |	d         |
d         g}|g| |d<   |t          |           k     dS dS )zsub divide bezier curver   r   r   r   r   N)rK   r   r   )rO   r   rP   p0r   r   p3rB   mdistonetwops               r   r   r     s    
c"gg++AYq\AYq\U1XU1X2r2D==FAA%c3//HCq6Bq1uIaL1vBqE!HQQQ(AcBqsG c"gg++++++r   c           	      z   t          j        g dg dg dg dg          }d}| D ]}t          |          dk     rt          |          D ]I\  }}|d||dz
           d         d	         z  |d         d         ||dz
           d         d         z
  z  z  }Jt	          dt          |                    D ]}t          j        ||dz
           d         d	         ||dz
           d         d	         ||         d	         d	         ||         d         d	         g          }t          j        ||dz
           d         d         ||dz
           d         d         ||         d	         d         ||         d         d         g          }t          j        ||          }	|d
t          j        |	|j                  z  z  }| S )zGet area in cubic sub-path)r   r   r   )r   r   r   )rH   rH   r   r   )r   rH   r   r   r   r   r   r   r   g333333?)numpyarrayrK   	enumeraterJ   matmulT)
rL   MAT_AREAarearO   r   coordrP   vec_xvec_yvexs
             r   csparear     s   {	~~~~~~F H D 6 6r77Q;;!" 	L 	LHAuC"QU)A,q/)U1Xa[2a!e9Q<?-JKKDDq#b''"" 	6 	6AKAE1a"QU)A,q/2a58A;1aL E KAE1a"QU)A,q/2a58A;1aL E ,uh//CD5<UW5555DD	6 5Lr   c           
         t          j        g dg dg dg dg          }t          j        g dg dg dg dg          }t          j        g d	g d
g dg dg          }t          j        g dg dg dg dg          }t          |           }d}d}t          |          dk     rt	          t          d                    | D ]}t          |          D ]\  }	}
|||	dz
           d         d         ||	dz
           d         d         |
d         d         z
  z  ||	dz
           d         d         ||	dz
           d         d         z   |
d         d         z   z  dz  z  }|||	dz
           d         d         |
d         d         ||	dz
           d         d         z
  z  ||	dz
           d         d         ||	dz
           d         d         z   |
d         d         z   z  dz  z  }t          dt          |                    D ]Q}t          j        ||dz
           d         d         ||dz
           d         d         ||         d         d         ||         d         d         g          }t          j        ||dz
           d         d         ||dz
           d         d         ||         d         d         ||         d         d         g          }||fd}t          j         ||           ||           ||           ||          g          }|t          j	        ||j
                  dz  z  }|t          j	        ||j
                  dz  z  }S| |z  | |z  fS )zGet cubic sub-path coefficient)r   #   
   )r         )r      )-   r   )r      r   )r   	      )r   r   r   )   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   )r   r   r   r   r   g:0yE>z-Area is zero, cannot calculate Center of Massr   r   r   r   c                 \    t          j        t          j        ||           |j                  S )N)r   r   r   )MATr   r   s      r   _mulzcspcofm.<locals>._mul  s"    |EL$<$<egFFFr   i  )r   r   r   r   
ValueErrorr   r   rJ   rK   r   r   )rL   
MAT_COFM_0
MAT_COFM_1
MAT_COFM_2
MAT_COFM_3r   xcycrO   r   r   rP   r   r   r   vec_ts                   r   cspcofmr     s   			+++->->->@Q@Q@QR J 	...///;K;K;KL J 	...///;K;K;KL J 			+++->->->@Q@Q@QR J 3<<D	B	B
4yy6JKKLLL 5 5!" 	 	HAu1q5	!Qa!e9Q<?U1Xa[02a!e9Q<?RAYq\!_4uQx{BD B 1q5	!Q8A;AE1a02a!e9Q<?RAYq\!_4uQx{BD BB q#b''"" 	5 	5AKAE1a"QU)A,q/2a58A;1aL E KAE1a"QU)A,q/2a58A;1aL E !&U G G G G Kj!!44
#3#3TT*5E5EttJGWGWX E %,ueg..44B%,ueg..44BB	5  3:sTz!!r   )r   )r   )r   r=   )r=   )r=   r   )r   )#__doc__r   r	   r   
transformsr   localizationr   r   r   r   r   r0   r4   r<   rC   rF   rR   rd   r{   ri   r   r   r7   r   r   r   r   rE   r?   r   r   r   r   r   r   r   r   <module>r      s  ,     + + + + + + , , , , , ,
     < < < <
& & &R  Q Q Q Q' ' ' '( ( ( (
 
 
* * *<  B    *  82 2 2$
< 
< 
<, , , ,"  $ $ $NY Y Y Y   $O O O     (  .4" 4" 4" 4" 4"r   