Extrapolating a line in MT

Thoughts, Help, Feature Requests, Bug Reports, Developing code for...

Moderators: dorpond, trevor, Azhrei

Forum rules
PLEASE don't post images of your entire desktop, attach entire campaign files when only a single file is needed, or generally act in some other anti-social behavior. :)
Post Reply
xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Extrapolating a line in MT

Post by xavram »

Hi all, just wondering if someone has done this. No sense in re-creating the wheel if its already been done.

Given that I know the location of the caster and a target, is there a way to determine all the MT cells that a line between them would pass through?

Ideally, there is a 3rd parameter here, its the tricky one. Given a caster, target, and length of the line, is there a way to determine the cells that a line from the caster to the target, plus any excess of the length of the line, would pass through? IE, caster draws a 40 foot line, going through a target 20 feet away and then an additional 20 feet after that?

This assumes the line is being draw from the center of the caster/target squares.

Thanks! if anyone has worked out some of this math (or something related), would appreciate you sharing it!

User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

Re: Extrapolating a line in MT

Post by wolph42 »

hi, im not sure i've got it completely covered as i worked on this a couple of years ago, but he BoT has these type of functions to calculate several grid areas given an mathematical shape (e.g. a line). You can check out the BoT (bag of tricks) link in sig. Hit the manual button, this should open several forms, one of them explaining macros that you can use for this.

User avatar
aliasmask
RPTools Team
Posts: 9024
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Extrapolating a line in MT

Post by aliasmask »

I imagine it would get tricky with 1:2:1 movement since it won't be using real distance. Then the size of tokens and elevations can confuse things as well. For example going from the center of source to a large target could be longer than the line, but the front squares of target could be within the distance. I have a distance formula that gets the minimum distance between 2 creatures. Taking the ratio between the x,y divided by the distance will give you the x,y step distances which will tell you the squares they fall in. For example. let's say target is 4x and 2y away which is 25ft in 1:2:1. Let's start the origin at 0,0. We want to check every 5 ft, so divide by 5 giving you 4/5 = 0.8 in x direction and 2/5 = 0.4.

step 0 (origin) 0,0
step 1 0.8, 0.4
step 2 1.6, 0.8
step 3 2.4, 1.2
step 4 3.2, 1.6
step 5 4.0, 2.0
...

Tricky part is how you determine which square each of these points are in. You could round to the nearest 50 so it looks like this when you round or round up.
round / round up
step 1 1,0 / 1,1
step 2 2,1 / 2,1
step 3 2,1 / 3,2
step 4 3,2 / 4,2
step 5 4,2 / 4,2

I think both are valid, but round up looks more natural in this case. This method you could just use the getDistance MT function and determine the intervening grid units in between and then beyond.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Extrapolating a line in MT

Post by xavram »

I actually got it worked out and its working fine with a square grid...but still not working for an Isometric grid.

Code: Select all

[h : casterToken = getSelected()]

[h : isoMod = 1]
[h, if(getTokenShape(casterToken) == "FIGURE"), code : {
	[h : copyId = findToken("LineBlock-Iso","0.TokenMap")]
	[h : isoMod = 2]
};
{
	[h : copyId = findToken("LineBlock","0.TokenMap")]
}]

[h : casterSize = getSize(casterToken)]
[h : centerXOffset = 25]
[h : centerYOffset = 25]
[h, if(casterSize == "Large"), code : {
	[h : centerXOffset = 50]
	[h : centerYOffset = 50]
}]
[h, if(casterSize == "Huge"), code : {
	[h : centerXOffset = 75]
	[h : centerYOffset = 75]
}]

[h : centerXOffset = centerXOffset*isoMod]

[h : originX = getTokenX(1,casterToken)+centerXOffset]
[h : originY = getTokenY(1,casterToken)+centerYOffset]
[h : originCellX = getTokenX(0,casterToken)]
[h : originCellY = getTokenY(0,casterToken)]

[h : metricUsed = "ONE_TWO_ONE"]
[h : range = json.set("", "from", 1, "upto", 150, "distancePerCell", 0, "metric", metricUsed, "token", casterToken)]
[h : cond = json.set("", "range", range, "visible", 1, "layer", "TOKEN")]
[h : validTargets = "[]"]
[h: ids = getTokens(",", cond)]
[h : targetNames = ""]
[h, foreach(id, ids) : targetNames = listAppend(targetNames, getName(id))]

[h : targetTokenInput = input("targetName|" + targetNames + "|Target|LIST|VALUE=STRING",
								"lineLength|10,20,30,40,50,60,70,80,90,100,110,120|Line Length|LIST|VALUE=STRING")]

[h : abort(targetTokenInput)]

<!--Has to be converted to pixels-->
[h : lineLength = eval(string(lineLength))]
[h : lineLength = lineLength * 10]

[h : targetId = findToken(targetName)]

[h : targetSize = getSize(targetId)]
[h : targetXOffset = 25]
[h : targetYOffset = 25]
[h, if(targetSize == "Large"), code : {
	[h : targetXOffset = 50]
	[h : targetYOffset = 50]
}]
[h, if(targetSize == "Huge"), code : {
	[h : targetXOffset = 75]
	[h : targetYOffset = 75]
}]
[h : targetXOffset = targetXOffset*isoMod]


[h : targetX = getTokenX(1, targetId)+targetXOffset]
[h : targetY = getTokenY(1, targetId)+targetYOffset]

[h : lengthToTarget = squareroot(Sum(square(targetX-originX),square(targetY-originY)))]

[h : unitSlopeX = (targetX-originX) / lengthToTarget]
[h : unitSlopeY = (targetY-originY) / lengthToTarget]

[h : endX = originX + unitSlopeX * lineLength]
[h : endY = originY + unitSlopeY * lineLength]

<!--Loop through the line, 10 pixels at a time-->
[h : passedThroughCells = "[]"]
[h : xCellSize = 50 * isoMod]
[h, for(x,0,Sum(lineLength,10),10), code : {
	[h : pointX = originX + unitSlopeX * x]
	[h : pointY = originY + unitSlopeY * x]
	<!--Convert to cell coordinates-->
	[h : pointX = round((pointX-25) / xCellSize)]
	[h : pointY = round((pointY-25) / 50)]	
	[h : passedThroughCells = json.append(passedThroughCells, json.set("", "X", pointX, "Y", pointY))]
}]

[h : passedThroughCells = json.union("[]", passedThroughCells)]
[h : passedThroughCells = json.remove(passedThroughCells, 0)]

[h, foreach(cell, passedThroughCells), code : {
	[h : copyToken(copyId,1,"0.TokenMap",json.set("","x",json.get(cell, "X"),"y",json.get(cell, "Y"),"useDistance",0,"name","LineBlock X"))]		
}]
[broadcast("origin = " + originX + ", " + originY)]
[broadcast(passedThroughCells)]


User avatar
JoeDuncan
Giant
Posts: 118
Joined: Sun Nov 22, 2020 9:02 pm

Re: Extrapolating a line in MT

Post by JoeDuncan »

Too bad you can't create a drawing programmatically from MTScript :(

If you could - it looks like you could just pull the path from the drawing info:

https://wiki.rptools.info/index.php/getDrawingInfo
"Joe's Ugly Hacks - Get 'em while their hot! Guaranteed ugliest hacks around or your money back!"

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Extrapolating a line in MT

Post by xavram »

Yeah, that is a shame...since I know the start/end of the line, draw it, then get the draw properties.

There is something in the Isometric grid that just makes this not work...something about how the grid is tilted/flattened that is messing things up.

User avatar
aliasmask
RPTools Team
Posts: 9024
Joined: Tue Nov 10, 2009 6:11 pm
Location: Bay Area

Re: Extrapolating a line in MT

Post by aliasmask »

xavram wrote:
Fri Dec 31, 2021 4:19 pm
Yeah, that is a shame...since I know the start/end of the line, draw it, then get the draw properties.

There is something in the Isometric grid that just makes this not work...something about how the grid is tilted/flattened that is messing things up.
Isn't just an offset for odd rows/columns depending on hex style.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Extrapolating a line in MT

Post by xavram »

AM, yep, that's what I'm thinking too...but just haven't been able to pin it down yet.

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Extrapolating a line in MT

Post by xavram »

Ha, got it to work..had to go back to some of my older math code, for determining Flank/Cover, and leverage some of that. But golden now.

One thing that did trip me up is that I had forgotten that MT is now defaulting maps to 100 pixels per cell instead of 50. So i had to change some my code to account for that but it got me thinking...is there a method in MT to determine the size of the cells on a given map? I could not find anything in the wiki for this, but it would be really helpful if there was, so I could change my code to check that and use whatever the given map was set to.

Thanks!

User avatar
Full Bleed
Demigod
Posts: 4736
Joined: Sun Feb 25, 2007 11:53 am
Location: FL

Re: Extrapolating a line in MT

Post by Full Bleed »

xavram wrote:
Tue Jan 04, 2022 11:11 am
One thing that did trip me up is that I had forgotten that MT is now defaulting maps to 100 pixels per cell instead of 50. So i had to change some my code to account for that but it got me thinking...is there a method in MT to determine the size of the cells on a given map? I could not find anything in the wiki for this, but it would be really helpful if there was, so I could change my code to check that and use whatever the given map was set to.

Thanks!
https://wiki.rptools.info/index.php/getInfo
Maptool is the Millennium Falcon of VTT's -- "She may not look like much, but she's got it where it counts."

xavram
Dragon
Posts: 891
Joined: Tue Apr 20, 2010 8:22 pm

Re: Extrapolating a line in MT

Post by xavram »

Awesome, GetInfo, thanks!

Post Reply

Return to “MapTool”