{"action":"created","issue":{"url":"https://api.github.com/repos/paperjs/paper.js/issues/799","labels_url":"https://api.github.com/repos/paperjs/paper.js/issues/799/labels{/name}","comments_url":"https://api.github.com/repos/paperjs/paper.js/issues/799/comments","events_url":"https://api.github.com/repos/paperjs/paper.js/issues/799/events","html_url":"https://github.com/paperjs/paper.js/issues/799","id":110103561,"number":799,"title":"Curve.getParameterOf() returns wrong values for small hooks at the end of curves.","user":{"login":"lehni","id":213275,"avatar_url":"https://avatars.githubusercontent.com/u/213275?v=3","gravatar_id":"","url":"https://api.github.com/users/lehni","html_url":"https://github.com/lehni","followers_url":"https://api.github.com/users/lehni/followers","following_url":"https://api.github.com/users/lehni/following{/other_user}","gists_url":"https://api.github.com/users/lehni/gists{/gist_id}","starred_url":"https://api.github.com/users/lehni/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/lehni/subscriptions","organizations_url":"https://api.github.com/users/lehni/orgs","repos_url":"https://api.github.com/users/lehni/repos","events_url":"https://api.github.com/users/lehni/events{/privacy}","received_events_url":"https://api.github.com/users/lehni/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/paperjs/paper.js/labels/boolean","name":"boolean","color":"fef2c0"},{"url":"https://api.github.com/repos/paperjs/paper.js/labels/clipping","name":"clipping","color":"d4c5f9"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":15,"created_at":"2015-10-06T21:19:13Z","updated_at":"2015-10-08T07:31:32Z","closed_at":null,"body":"Here is an example that illustrates it well. \r\n\r\nIt works as it should in this [Sketch Demo](http://sketch.paperjs.org/#S/lVTbattAEP2VxS+Sibrs/SLTp6SFPBQKeYxDUOSNI6KsiiQnhZB/7+xKjiXHgXQxhp05M2fmzKxeF754cot8cfXo+vJhkS3KZhPuz5V7wbdPRd9Wf9F35N0L+hUv6bUVVkqlsRZSS6utyRCJvxOOb4JyxoiQ1GJrrJCCg5ESwY1izCgsrJaamJvlau3X/rloUblrnx0dOc/DJeVWY64NI5IaoYSFHIpjzonWkjPJqGEZ+hJIcImpplZJsMK/zBAlUBqnUghGlAWg/iIslPxeMJsVfBzPP8bzdxroH0ycM25HGDOSCsIFNCNMgHFMlFHGUiuYhhyAoxS0YwpSKs2J0QpwzGIuiOVaEcKs1ANMEmkUqKMFgQkMQt/vfNlXjUdl64re/S76hzT2kaGyqZt2iV7XHsFpXb9rfWwtgkZzOJ3bPjnfdzm6jqF4NNAMze7sJpsE9W3z6M4DRz5QfXBelUVd+W2O7ou6c4P3LZT9dqLy86ota5dWvneHosNU/kC1MJPowOGyGnxl47umdrhutmkSWkKXFzlK0FmMwNXmUM4ZSjKwtvBCIMkA2ucbjcfgBvwzYDAsVye1xGPtE0lL5yPTJHgiT1tsqh3ITTAJh34ma2xkYvlPhffqhTd4vB4w26R1m2S/+wHHTuDgqSV39c4lh3cde+pcHF4HIZECb11/OXWkMWOImg3qZ7Pzm4OuezSund/CCEH8uSOPxHPsfdP+KMqHdL9Bw9JkqHrfmxnltKyBOdAMiSP4w/7hKd/nsOWpTbyour7wpTvenSDQ3neCZVywOLvlCj7fd0D3GI3dIr++efsH) using the old code-base.\r\n\r\nBut on the `boolean-fix` branch, the following output is printed. You can see how the second iteration gets the wrong parameter for the location on Path ID 1, and the two points have a distance between them that's way too big.\r\n\r\n```\r\nFound 2 intersections:\r\nIntersection 0:\r\nPath ID: 3, parameter: 0, point: { x: 435.17197, y: 109.93154 }\r\nPath ID: 1, parameter: 1, point: { x: 435.17197, y: 109.93154 }\r\nDistance 1.9742350317315248e-13\r\nIntersection 1:\r\nPath ID: 3, parameter: 0.0018325208116727982, point: { x: 435.17197, y: 109.93154 }\r\nPath ID: 1, parameter: 1, point: { x: 435.17197, y: 109.93154 }\r\nDistance 0.0000011446932516827401\r\n```\r\n\r\n```js\r\nview._matrix = new Matrix([9495567.745759798, 0, 0, 9495567.745759798, -4132204519.9894543, -1043862286.4975708]);\r\n\r\nvar curve1 = new Curve(397.3782051846493, 63.3307753252182, 397.3782051846493, 63.3307753252182, 435.1719657759655, 109.93154420692527, 435.1719657759655, 109.93154420692527);\r\nvar curve2 = new Curve(435.1719657759653, 109.93154420692537, 435.1757020633239, 109.92851403482048, 433.06868919427154, 111.49269316730876, 429.3409376002957, 111.50586397740894);\r\n\r\nfunction createPath(curve, color) {\r\n    return new Path({\r\n        segments: [curve.segment1, curve.segment2],\r\n        strokeColor: color,\r\n        strokeScaling: false\r\n    });\r\n}\r\n\r\nfunction createCircle(inter) {\r\n    var path = inter.path;\r\n    console.log('Path ID: ' + path.id\r\n        + ', parameter: ' + inter.parameter\r\n        + ', point: ' + inter.point);\r\n    return new Path.Circle({\r\n        center: inter.point,\r\n        radius: 0.000001,\r\n        strokeColor: path.strokeColor,\r\n        strokeScaling: false\r\n    });\r\n}\r\n\r\nvar path1 = createPath(curve1, 'red');\r\nvar path2 = createPath(curve2, 'blue');\r\n\r\nvar intersections = path1.getIntersections(path2);\r\nconsole.log('Found ' + intersections.length + ' intersections:');\r\nintersections.forEach(function(inter, i) {\r\n    console.log('Intersection ' + i + ':');\r\n    createCircle(inter.intersection);\r\n    createCircle(inter);\r\n    console.log('Distance ' + inter.point.getDistance(inter.intersection.point));\r\n});\r\n```"},"comment":{"url":"https://api.github.com/repos/paperjs/paper.js/issues/comments/146443375","html_url":"https://github.com/paperjs/paper.js/issues/799#issuecomment-146443375","issue_url":"https://api.github.com/repos/paperjs/paper.js/issues/799","id":146443375,"user":{"login":"iconexperience","id":2122773,"avatar_url":"https://avatars.githubusercontent.com/u/2122773?v=3","gravatar_id":"","url":"https://api.github.com/users/iconexperience","html_url":"https://github.com/iconexperience","followers_url":"https://api.github.com/users/iconexperience/followers","following_url":"https://api.github.com/users/iconexperience/following{/other_user}","gists_url":"https://api.github.com/users/iconexperience/gists{/gist_id}","starred_url":"https://api.github.com/users/iconexperience/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/iconexperience/subscriptions","organizations_url":"https://api.github.com/users/iconexperience/orgs","repos_url":"https://api.github.com/users/iconexperience/repos","events_url":"https://api.github.com/users/iconexperience/events{/privacy}","received_events_url":"https://api.github.com/users/iconexperience/received_events","type":"User","site_admin":false},"created_at":"2015-10-08T07:31:32Z","updated_at":"2015-10-08T07:31:32Z","body":"My case above seems to be a numerical precision issue. If I change things just slightly, like two lines in <a href=\"https://github.com/paperjs/paper.js/blob/develop/src/path/Curve.js#L1334\">getConvexHull()</a> from\r\n```\r\ndist1 = dq1 - (dq0 + (dq3 - dq0) / 3),\r\ndist2 = dq2 - (dq0 + 2 * (dq3 - dq0) / 3),\t\t\t\r\n```\r\n\r\n to\r\n```\r\ndist1 = dq1 - 2 / 3* dq0 - dq3 / 3,\r\ndist2 = dq2 - dq0 / 3 - 2 / 3 * dq3,\r\n```\r\nwhich should be absolutely equivalent, the self intersection is calculated much faster."}}