Standalone library to get all intersections between 2 SVG paths
npm install svg-path-intersectionsA commands with concatenated largeArc, sweep and final on-path parameters "bomb" quite a few other libraries).
svgEl() helper
let intersections = findPathIntersections(d1, d2)
`
or use it alongside with other path data parsers like Jarek Foksa's pathdata-polyfill and pass already parsed path data arrays to the findPathDataIntersections() method.
`
let checkCollision = checkCollision(pathData1, pathData2) // returns true or false
`
$3
`
`
or
`
`
`
let d1 = 'M 75 0 a 1 1 45 010 100 1 1 45 010 -100'
let d2 = 'M 50 0 a 1 1 45 010 100 1 1 45 010 -100'
let intersections= findPathIntersections(d1, d2);
console.log(JSON.stringify(intersections, null, ' '));
`
$3
`
const pathIntersections = require('svg-path-intersections');
const {findPathIntersections, checkPathIntersection, findPathDataIntersections, pointAtT, parsePathDataNormalized} = pathIntersections;
let d1 = 'M 75 0 a 1 1 45 010 100 1 1 45 010 -100'
let d2 = 'M 50 0 a 1 1 45 010 100 1 1 45 010 -100'
let intersections= findPathIntersections(d1, d2);
console.log(JSON.stringify(intersections, null, ' '));
`
Parameters/Options
| Option | values/default | Effect |
|--|--|--|
| pathData1, pathData2 | path data input | accepts stringified pathdata or parsed arrays |
| stopAtFirst | false | stop search after first occurrence: helps to speed up processing e.g. for collision checks |
| quality | low, medium, high | default: "medium"; higher quality results in more accurate coordinates and t values at the cost of longer processing times |
Methods
* findPathIntersections(pathData1, pathData2, stopAtFirst, quality) : finds all intersections
* checkCollision(d1, d2): stops at first intersection – faster than finding all occurences
* pointAtT(points, t): calculates point at t value for lines, quadratic or cubic béziers:
* cubic bézier: pointAtT([{x:0, y:0}, {x:0, y:0}, {x:0, y:0}, {x:0, y:0} ], 0.5)
(1. previous end point, 2. first control point, 3. second control point, 4. final on-path point)
* quadratic bézier: pointAtT([{x:0, y:0}, {x:0, y:0}, {x:0, y:0} ], 0.5)
(1. previous end point, 2. first control point, 3. final on-path point)
* lineto pointAtT([{x:0, y:0}, {x:0, y:0}], 0.5)
(1. previous end point, 2. final on-path point)
* parsePathDataNormalized(d, options)
Parse stringified pathdata to array with normalization options. See complete version with all options
Default options: toAbsolute, toLonghands, arcToCubics
$3
You can use this helper to add all svg geometry elements like so
`
let circle = svgEl(cx:10, cy:10, r: 10);
let ellipse = svgEl(cx:10, cy:10, rx: 10, ry:20 );
let path = svgEl(d: 'M 75 0 a 1 1 45 010 100 1 1 45 010 -100' );
// accepts an array of numbers or a string
let polygon = svgEl(points: '70 50 70 50 67.7 61.5 61.2 71.2 51.5 77.7 40 80 28.5 77.7 18.8 71.2 12.3 61.5 10 50 12.3 38.5 18.8 28.8 28.5 22.3 40 20 51.5 22.3 61.2 28.8 67.7 38.5' );
let polyline = svgEl(points: '70 50 70 50 67.7 61.5 61.2 71.2 51.5 77.7 40 80 28.5 77.7 18.8 71.2 12.3 61.5 10 50 12.3 38.5 18.8 28.8 28.5 22.3 40 20 51.5 22.3 61.2 28.8 67.7 38.5', type:'polyline' );
let rect = svgEl(x:10, y:10, width:50, height:50, rx:5, ry:3)
let line = svgEl(x1:10, y1:10, x2:50, y2:50)
// get intersections between shapes
let intersections = findPathIntersections(circle, path)
`
$3
`
let circle = document.querySelector('circle')
let path = document.querySelector('path')
let intersectionsDOM = getElementIntersections(circle, path)
`
$3
* Codepen: multiple path examples and speed test
* Simple demo
* Shapes
$3
The returned intersection array contains:
* x/y coordinates for each intersection
* t1 and t2 values for 1. and 2. path segments
* segment indices (at which intersection occurred)
* segment command points (cpts1 and cpts2)
This way, you can calculate coordinates for both paths or split each path at t values.
`
[
{
"x": 62.50000000097887,
"y": 98.40012176975786,
"t1": 0.15651097923256496,
"t2": 0.8434890204109524,
"segment1": 3,
"segment2": 2,
"cpts1": [
{
"x": 74.99999998680912,
"y": 100
},
{
"x": 47.410749986809115,
"y": 99.99999999272146
},
{
"x": 24.999999992721463,
"y": 77.5892499868091
},
{
"x": 25.000000000000014,
"y": 49.9999999868091
}
],
"cpts2": [
{
"x": 100,
"y": 50.000000013190885
},
{
"x": 99.99999999272146,
"y": 77.58925001319088
},
{
"x": 77.58924998680911,
"y": 100.00000000727853
},
{
"x": 49.999999986809115,
"y": 100
}
]
},
{
"x": 62.49999999505845,
"y": 1.5998782311929203,
"t1": 0.8434890203595754,
"t2": 0.15651097928396177,
"segment1": 4,
"segment2": 1,
"cpts1": [
{
"x": 25.000000000000014,
"y": 49.9999999868091
},
{
"x": 25.000000007278558,
"y": 22.41074998680911
},
{
"x": 47.410750013190906,
"y": -7.278536884314235e-9
},
{
"x": 75.0000000131909,
"y": 1.4210854715202004e-14
}
],
"cpts2": [
{
"x": 50,
"y": 0
},
{
"x": 77.58925001319088,
"y": 7.278543989741593e-9
},
{
"x": 100.00000000727853,
"y": 22.4107500131909
},
{
"x": 100,
"y": 50.000000013190885
}
]
}
]
``