Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

[HELP Path Math] Path Collision

Hello everyone. I am using Path Math to detect collision between paths, on one side I have Dynamic Lighting walls, and the other is a dynamic path between two tokens. Basically I'm trying to determine line of sight. I have all paths 'popped' into Path Math objects, and that seems to work fine, but when I ask Path Math to check for intersections, I get no positives. I even tried placing a wall right smack between the two tokens. I'm guessing I am doin something wrong? I would be thankful for any help. Here is the relevant code: var pid=chartokens[0].get('pageid'); var segments1=[]; var segments2=[]; var paths1=[]; var paths2=[]; var paths=findObjs({"_type":"path","_pageid":pid,"layer":"walls"}); for (var p in paths) { paths1[paths1.length]=new PathMath.Path(paths[p]); } for (var token in tokens) { if (chartokens[0].get("left")!=tokens[token].get("left") && chartokens[0].get("top")!=tokens[token].get("top")) { var left = Math.min(chartokens[0].get("left"),tokens[token].get("left")); var right = Math.max(chartokens[0].get("left"),tokens[token].get("left")); var top = Math.min(chartokens[0].get("top"),tokens[token].get("top")); var bottom = Math.max(chartokens[0].get("top"),tokens[token].get("top")); var width = right-left; var height = bottom-top; var cx = left + width/2; var cy = top + height/2; _path=[["M",chartokens[0].get("left"),chartokens[0].get("top")],["L",tokens[token].get("left"),tokens[token].get("top")]]; var pathObj={ _path: JSON.stringify(_path), left: cx, top: cy, width: width, height: height, stroke: '#ff0000', _pageid: chartokens[0].get('pageid'), layer: 'walls' } var newPath = createObj('path', pathObj); paths2[paths2.length]=new PathMath.Path(newPath); newPath.remove(); } } for (var _i in paths1) { for (var _n in paths2) { log(paths1[_i].intersects(paths2[_n])) } }
1663845587
David M.
Pro
API Scripter
Have you logged your paths2 array to see if it is populated correctly?  Never used PathMath, but my guess is that since createObj is asynchronous it prob doesn't yet exist when you try to copy it to your new PathMath object. You may want to try an async await approach to ensure the path object exists before continuing. 
1663847467

Edited 1663848229
David M.
Pro
API Scripter
Hmm, I'm also not sure if your SVG coordinates are going to be correct, since you are assigning the token's map coordinates to your SVG points. Roll20 path objects have a center (left/top) that are in the map coordinate system, but the control pts (M,L,etc.) are all relative to the size of the bounding box  of the points within the path  (determined by the path width/height) . In other words, the upper left point in the path coordinate system will always be (0,0), but that might be at map coordinate (275,175) for example.  Seems like you would need a translation function. I did a little bit of LoS work (not using PathMath) in my Radar script, though it is a bit more complicated because I'm checking the center of one token to the center and all four corners of another token.  Line 2021 in the Radar code  starts all the LoS business. It creates an array of pseudo path segments, filtering out those segments that are outside of a region of interest around a source token (in Radar's case, based on the range of the Radar sensor), converting the Path coordinates to actual map coordinates, then checking for intersections of (1) the "lines" between the center of the source token and the 5 "critical points" and (2) the pseudo path segments.  It's a PITA, for sure.  Anyway, you might find some useful bits in there for the path <--> map coordinate conversions, at least (assuming you want to stick with PathMath). EDIT  - one advantage of the pseudo path segment approach is that you don't have to use createObj and .remove so no async issues to deal with.
Thank you so much. You are right that I would need some sort of conversion, I got it to kind of work a bit, though the results are all over the place. I'll take a look at your radar script. Looking at the image, that would pretty much be what I would need.
So, David. Just wanted to thank you for pointing out your radar script to me. After browsing through the code for it, I figured that I could simply just use it instead of writing my own version. So I added a few lines to it and got it to write the resulting array to the target tokens character sheet in a hidden field. And I still have access to the 'normal' radar output for my players' mystical senses. So, again. Thank you. Saved me from hours upon hours of work. 
1663936518
David M.
Pro
API Scripter
Awesome! And just because I'm curious: what array are you storing? Tokens within LoS? Do you have another script that uses this info? 
1663943783
Gauss
Forum Champion
David, how easy would it be to update your radar script to use a corner to 4 corners check instead? Some game systems use the corner of the token as the starting point.  Obviously it would quadruple the checks since it would have to check each of 4 corners (or at least the 2 closest to the target).
1663947360
David M.
Pro
API Scripter
Hmm, good point about LoS from corner. Shouldn't be too hard to add a switch for that. Won't be able to look at in until Sunday at the earliest, though.
Yeah, I have a target dropdown that is populated by targets based on Weapon Ranges, distance between tokens and LoS. And the same for spells. At first it just found all tokens on the map and put them in as targets, but with twenty or so tokens, all spread over the map, it became a bit of a hsstle to figure out what target to select to get the right enemy.
1664024267
David M.
Pro
API Scripter
Neat!