{"id":1759,"date":"2017-03-29T23:38:08","date_gmt":"2017-03-30T04:38:08","guid":{"rendered":"https:\/\/rpchurchill.com\/wordpress\/?p=1759"},"modified":"2017-09-15T07:32:44","modified_gmt":"2017-09-15T12:32:44","slug":"a-simple-discrete-event-simulation-part-89","status":"publish","type":"post","link":"https:\/\/rpchurchill.com\/wordpress\/posts\/2017\/03\/29\/a-simple-discrete-event-simulation-part-89\/","title":{"rendered":"A Simple Discrete-Event Simulation: Part 89"},"content":{"rendered":"<p><iframe loading=\"lazy\" width=\"426px\" height=\"1015px\" src=\"https:\/\/www.rpchurchill.com\/demo\/des\/discrete-event-sim_20170329.html\" frameborder=\"0\" allowfullscreen><\/iframe><\/p>\n<p><a href=\"https:\/\/www.rpchurchill.com\/demo\/des\/discrete-event-sim_20170329.html\">Direct link<\/a> for mobile devices.<\/p>\n<p>I was walking a few miles in the nice weather this evening when two possible solutions popped into my head for the DisplayGroup drag problem I had in the simulation app (where the pointer arrow from the edge of the DisplayGroup object to the edge of the DisplayItem object does not get drawn if the intersection tests generate false negatives).  As long as the idea was fresh I figured I&#8217;d go ahead and check it out.  It turned out that I already do one of things that occurred to me so that quickly proved to be a dead end.  The other idea appears to solve the problem for all the cases I&#8217;ve tested.<\/p>\n<p>The problem I found with the method I originally implemented solved for the intersection of two lines using the slope and y-intercept formula.  The problem with that is that some values for the y-intercept can be quite high which can lead to rounding errors at the intersection point.  If I write formulas for the lines in terms of one of the endpoints of each line then the formulas get slightly more complex but the accuracy of calculating the intersection point should increase.<\/p>\n<p>The point-slope formula for a line is:<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;y<sub>p<\/sub> = y<sub>1<\/sub> + m<sub>12<\/sub> * (x<sub>p<\/sub> &#8211; x<sub>1<\/sub>)<\/p>\n<p>where:<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;x<sub>p<\/sub>, y<sub>p<\/sub> = location of arbitrary point on line<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;m<sub>12<\/sub> = slope of line, (y<sub>2<\/sub> &#8211; y<sub>1<\/sub>) \/ (x<sub>2<\/sub> &#8211; x<sub>1<\/sub>)<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;x<sub>1<\/sub>, y<sub>1<\/sub> = location of line endpoint 1<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;x<sub>2<\/sub>, y<sub>2<\/sub> = location of line endpoint 2<\/p>\n<p>Substituting for the y<sub>p<\/sub> we look to solve for x<sub>p<\/sub> for the intersection of lines 12 and 34<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;y<sub>1<\/sub> + m<sub>12<\/sub> * (x<sub>p<\/sub> &#8211; x<sub>1<\/sub>) = y<sub>3<\/sub> + m<sub>34<\/sub> * (x<sub>p<\/sub> &#8211; x<sub>3<\/sub>)<\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;y<sub>1<\/sub> + m<sub>12<\/sub> * x<sub>p<\/sub> &#8211; m<sub>12<\/sub> * x<sub>1<\/sub> = y<sub>3<\/sub> + m<sub>34<\/sub> * x<sub>p<\/sub> &#8211; m<sub>34<\/sub> * x<sub>3<\/sub><\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;m<sub>12<\/sub> * x<sub>p<\/sub> &#8211; m<sub>34<\/sub> * x<sub>p<\/sub> = y<sub>3<\/sub> &#8211; y<sub>1<\/sub> + m<sub>12<\/sub> * x<sub>1<\/sub> &#8211; m<sub>34<\/sub> * x<sub>3<\/sub><\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;x<sub>p<\/sub> * (m<sub>12<\/sub> &#8211; m<sub>34<\/sub>) = y<sub>3<\/sub> &#8211; y<sub>1<\/sub> + m<sub>12<\/sub> * x<sub>1<\/sub> &#8211; m<sub>34<\/sub> * x<sub>3<\/sub><\/p>\n<p>&nbsp;&nbsp;&nbsp;&nbsp;x<sub>p<\/sub> = (y<sub>3<\/sub> &#8211; y<sub>1<\/sub> + m<sub>12<\/sub> * x<sub>1<\/sub> &#8211; m<sub>34<\/sub> * x<sub>3<\/sub>) \/ (m<sub>12<\/sub> &#8211; m<sub>34<\/sub>)<\/p>\n<p>Once you have the x-coordinate then you get the y-coordinate by reinvoking the first formula.  The code has to do some testing for special cases involving vertical and horizontal lines as shown in the new <code>intersection<\/code> function here:<\/p>\n<pre class=\"toolbar-overlay:false wrap:false height-set:true lang:default decode:true \">\r\n    function intersection(x1,y1,x2,y2,x3,y3,x4,y4) {\r\n      \/\/see if line12 crosses line34 between the endpoints of both lines\r\n      var m12; var b1;\r\n      var m34; var b2;\r\n      var ix; var iy;\r\n      if (x1 != x2) {  \/\/first line not vertical\r\n        m12 = (y2 - y1) \/ (x2 - x1);\r\n        if (x3 != x4) {  \/\/second line not vertical\r\n          m34 = (y4 - y3) \/ (x4 - x3);\r\n          \r\n          if (m12 != m34) {\r\n            if (y3 != y4) {  \/\/edge not horizontal\r\n              ix = (y3 - y4 + m12 * x1 - m34 * x3) \/ (m12 - m34);\r\n              iy = y1 + (ix - x1) * m12;\r\n            } else if (y1 != y2) {\r\n              iy = y3;\r\n              \/\/ix = (iy - y1 + x1 * m12) \/ m12;  \/\/save some clocks by rewriting as next line\r\n              ix = (iy - y1) \/ m12 + x1;\r\n            } else {\r\n              \/\/both lines horizontal therefore parallel\r\n              return false;\r\n            }\r\n          } else {\r\n            \/\/should not need to explicitly test for overlapping parallel lines for convex shapes\r\n            return false;\r\n          }\r\n        } else {         \/\/second line is vertical\r\n          ix = x3;\r\n          iy = y1 + (ix - x1) * m12;\r\n        }\r\n      } else {         \/\/first line vertical\r\n        if (x3 != x4) {  \/\/second line is not vertical\r\n          m34 = (y4 - y3) \/ (x4 - x3);\r\n          \r\n          ix = x1;\r\n          iy = y3 + (ix - x3) * m34;\r\n        } else {\r\n          \/\/if this happens then no intersection\r\n          return false;\r\n        }\r\n      }\r\n      if (!(((ix >= x1) && (ix <= x2)) || ((ix >= x2) && (ix <= x1)))) {\r\n        return false;\r\n      }\r\n      if (!(((iy >= y1) && (iy <= y2)) || ((iy >= y2) && (iy <= y1)))) {\r\n        return false;\r\n      }\r\n      if (!(((ix >= x3) && (ix <= x4)) || ((ix >= x4) && (ix <= x3)))) {\r\n        return false;\r\n      }\r\n      if (!(((iy >= y3) && (iy <= y4)) || ((iy >= y4) && (iy <= y3)))) {\r\n        return false;\r\n      }\r\n      \/\/if we haven't failed to this point then return values \r\n      return {x: ix, y: iy};\r\n    }\r\n<\/pre>\n<p>Click or tap on any of the non-path objects to make the associated DisplayGroup object visible, then drag that object around the screen with the mouse or by touch.  The pointer appears to render smoothly in all cases.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Direct link for mobile devices. I was walking a few miles in the nice weather this evening when two possible solutions popped into my head for the DisplayGroup drag problem I had in the simulation app (where the pointer arrow &hellip; <a href=\"https:\/\/rpchurchill.com\/wordpress\/posts\/2017\/03\/29\/a-simple-discrete-event-simulation-part-89\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[121,164,49,148,163,161],"_links":{"self":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1759"}],"collection":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/comments?post=1759"}],"version-history":[{"count":6,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1759\/revisions"}],"predecessor-version":[{"id":1765,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/posts\/1759\/revisions\/1765"}],"wp:attachment":[{"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/media?parent=1759"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/categories?post=1759"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rpchurchill.com\/wordpress\/wp-json\/wp\/v2\/tags?post=1759"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}