@@ -397,8 +397,13 @@ function filters(
397
397
relSubpoint = [ 0 , 0 ] ,
398
398
pathBase = [ 0 , 0 ] ,
399
399
prev = { } ;
400
+ /** @type {Point | undefined } */
401
+ let qControlPoint ;
400
402
401
403
path = path . filter ( function ( item , index , path ) {
404
+ const qPoint = qControlPoint ;
405
+ qControlPoint = undefined ;
406
+
402
407
let command = item . command ;
403
408
let data = item . args ;
404
409
let next = path [ index + 1 ] ;
@@ -795,14 +800,24 @@ function filters(
795
800
// t + q → t + t
796
801
else if (
797
802
// @ts -ignore
798
- prev . command === 't' &&
799
- // @ts -ignore
800
- Math . abs ( data [ 2 ] - prev . args [ 0 ] ) < error &&
801
- // @ts -ignore
802
- Math . abs ( data [ 3 ] - prev . args [ 1 ] ) < error
803
+ prev . command === 't'
803
804
) {
804
- command = 't' ;
805
- data = data . slice ( 2 ) ;
805
+ // @ts -ignore
806
+ const predictedControlPoint = reflectPoint ( qPoint , item . base ) ;
807
+ const realControlPoint = [
808
+ // @ts -ignore
809
+ data [ 0 ] + item . base [ 0 ] ,
810
+ // @ts -ignore
811
+ data [ 1 ] + item . base [ 1 ] ,
812
+ ] ;
813
+ if (
814
+ Math . abs ( predictedControlPoint [ 0 ] - realControlPoint [ 0 ] ) <
815
+ error &&
816
+ Math . abs ( predictedControlPoint [ 1 ] - realControlPoint [ 1 ] ) < error
817
+ ) {
818
+ command = 't' ;
819
+ data = data . slice ( 2 ) ;
820
+ }
806
821
}
807
822
}
808
823
}
@@ -873,6 +888,18 @@ function filters(
873
888
)
874
889
return false ;
875
890
891
+ if ( command === 'q' ) {
892
+ // @ts -ignore
893
+ qControlPoint = [ data [ 0 ] + item . base [ 0 ] , data [ 1 ] + item . base [ 1 ] ] ;
894
+ } else if ( command === 't' ) {
895
+ if ( qPoint ) {
896
+ // @ts -ignore
897
+ qControlPoint = reflectPoint ( qPoint , item . base ) ;
898
+ } else {
899
+ // @ts -ignore
900
+ qControlPoint = item . coords ;
901
+ }
902
+ }
876
903
prev = item ;
877
904
return true ;
878
905
} ) ;
@@ -1138,6 +1165,17 @@ function getDistance(point1, point2) {
1138
1165
return Math . hypot ( point1 [ 0 ] - point2 [ 0 ] , point1 [ 1 ] - point2 [ 1 ] ) ;
1139
1166
}
1140
1167
1168
+ /**
1169
+ * Reflects point across another point
1170
+ *
1171
+ * @param {Point } input
1172
+ * @param {Point } base
1173
+ * @returns {Point }
1174
+ */
1175
+ function reflectPoint ( input , base ) {
1176
+ return [ 2 * base [ 0 ] - input [ 0 ] , 2 * base [ 1 ] - input [ 1 ] ] ;
1177
+ }
1178
+
1141
1179
/**
1142
1180
* Returns coordinates of the curve point corresponding to the certain t
1143
1181
* a·(1 - t)³·p1 + b·(1 - t)²·t·p2 + c·(1 - t)·t²·p3 + d·t³·p4,
0 commit comments