{"id":2297,"date":"2014-07-07T01:18:06","date_gmt":"2014-07-07T05:18:06","guid":{"rendered":"http:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/?p=2297"},"modified":"2014-07-07T01:18:06","modified_gmt":"2014-07-07T05:18:06","slug":"circle-intersection-test","status":"publish","type":"post","link":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2014\/07\/circle-intersection-test\/","title":{"rendered":"Circle Intersection Test"},"content":{"rendered":"<p>Yet another quick test for a geometry function:<\/p>\n\n<!-- iframe plugin v.6.0 wordpress.org\/plugins\/iframe\/ -->\n<iframe loading=\"lazy\" src=\"http:\/\/rocketshipgames.com\/tmp\/20140707-circletest.html\" width=\"100%\" height=\"300\" scrolling=\"yes\" class=\"iframe-class\" frameborder=\"0\"><\/iframe>\n\n<p>Click, drag, and release to draw a line. A point will be drawn at the intersections if there are any. Hit &#8216;S&#8217; to toggle between treating the drawn segment as a line segments or a line.<\/p>\n<p>The demo uses some basic <a href=\"http:\/\/phaser.io\/\">Phaser<\/a> features for the interaction and drawing. The Javascript code is:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar game = new Phaser.Game(530, 300, Phaser.CANVAS, 'container',\r\n                           { create: create, update: update, render: render });\r\n\r\nvar line;\r\n\r\nvar setting;\r\n\r\nvar result1;\r\nvar result2;\r\n\r\nvar circle;\r\n\r\nvar segment = true;\r\n\r\nfunction create() {\r\n\r\n  line = new Phaser.Line(game.world.width\/4, game.world.height\/4,\r\n                         3*game.world.width\/4, 3*game.world.height\/4);\r\n\r\n  circle = new Phaser.Circle(game.world.width\/2, game.world.height\/2,\r\n                             Math.min(game.world.height, game.world.width)\/2);\r\n\r\n  game.input.onDown.add(click, this);\r\n  setting = false;\r\n\r\n  result1 = new Phaser.Point();\r\n  result2 = new Phaser.Point();\r\n\r\n    game.input.keyboard.addKey(Phaser.Keyboard.S)\r\n        .onDown.add(function() {\r\n            segment = !segment;\r\n        }, this);\r\n}\r\n\r\n\r\nfunction update() {\r\n\r\n    if (setting) {\r\n        line.end.set(game.input.activePointer.x,\r\n                      game.input.activePointer.y);\r\n\r\n        if (!game.input.activePointer.isDown) {\r\n            setting = false;\r\n        }\r\n    }\r\n}\r\n\r\n\r\nfunction click(pointer) {\r\n    setting = true;\r\n    line.start.set(pointer.x, pointer.y);\r\n}\r\n\r\n\r\nfunction render() {\r\n  game.debug.geom(line);\r\n\r\n  game.debug.geom(circle, '#00ff00', false, 2);\r\n\r\n  var res = intersection(line, circle, result1, result2, segment);\r\n  if (res) {\r\n    result1.x--;\r\n    result1.y--;\r\n    result2.x--;\r\n    result2.y--;\r\n\r\n    game.debug.geom(result1, '#ff0000');\r\n\r\n    if (res == INTERSECTION)\r\n      game.debug.geom(result2, '#ff0000');\r\n  }\r\n\r\n}\r\n\r\n\r\nvar NO_INTERSECTION = 0;\r\nvar INTERSECTION = 1;\r\nvar SINGLE_INTERSECTION = 2;\r\nvar TANGENT = 3;\r\n\r\nfunction intersection(line, circle, result1, result2, segment) {\r\n  var lx = line.end.x - line.start.x;\r\n  var ly = line.end.y - line.start.y;\r\n\r\n  var len = Math.sqrt(lx*lx + ly*ly);\r\n\r\n  var dx = lx \/ len;\r\n  var dy = ly \/ len;\r\n\r\n  var t = dx*(circle.x-line.start.x) + dy*(circle.y-line.start.y);\r\n\r\n  var ex = t * dx + line.start.x;\r\n  var ey = t * dy + line.start.y;\r\n\r\n  var lec = Math.sqrt((ex-circle.x)*(ex-circle.x) +\r\n                      (ey-circle.y)*(ey-circle.y));\r\n\r\n  if (lec &lt; circle.radius) {\r\n\r\n    var dt = Math.sqrt(circle.radius*circle.radius - lec*lec);\r\n\r\n    var te = dx*(line.end.x-line.start.x) + dy*(line.end.y-line.start.y);\r\n\r\n    if (segment) {\r\n      if ((t-dt &lt; 0 || t-dt &gt; te) &amp;&amp;\r\n          (t+dt &lt; 0 || t+dt &gt; te)) {\r\n            return NO_INTERSECTION;\r\n      } else if (t-dt &lt; 0 || t-dt &gt; te) {\r\n          result1.x = (t+dt)*dx + line.start.x;\r\n          result1.y = (t+dt)*dy + line.start.y;\r\n          return SINGLE_INTERSECTION;\r\n      } else if (t+dt &lt; 0 || t+dt &gt; te) {\r\n          result1.x = (t-dt)*dx + line.start.x;\r\n          result1.y = (t-dt)*dy + line.start.y;\r\n          return SINGLE_INTERSECTION;\r\n      }\r\n    }\r\n\r\n    result1.x = (t-dt)*dx + line.start.x;\r\n    result1.y = (t-dt)*dy + line.start.y;\r\n\r\n    result2.x = (t+dt)*dx + line.start.x;\r\n    result2.y = (t+dt)*dy + line.start.y;\r\n\r\n    return INTERSECTION;\r\n  } else if (lec == circle.radius) {\r\n\r\n    result1.x = ex;\r\n    result1.y = ey;\r\n\r\n    result2.x = ex;\r\n    result2.y = ey;\r\n\r\n    return TANGENT;\r\n  }\r\n\r\n  return NO_INTERSECTION;\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Yet another quick test for a geometry function: Click, drag, and release to draw a line. A point will be drawn at the intersections if there are any. Hit &#8216;S&#8217; to toggle between treating the drawn segment as a line segments or a line. The demo uses some basic Phaser features for the interaction and &hellip; <a href=\"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/2014\/07\/circle-intersection-test\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":7615,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[58],"tags":[257,104,162,401,277],"class_list":["post-2297","post","type-post","status-publish","format-standard","hentry","category-code","tag-featured","tag-html5","tag-javascript","tag-math","tag-videogames"],"_links":{"self":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/2297","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/comments?post=2297"}],"version-history":[{"count":1,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/2297\/revisions"}],"predecessor-version":[{"id":2298,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/posts\/2297\/revisions\/2298"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/media\/7615"}],"wp:attachment":[{"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/media?parent=2297"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/categories?post=2297"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rocketshipgames.com\/blogs\/tjkopena\/wp-json\/wp\/v2\/tags?post=2297"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}