So I'm trying to check if a location is between a box using vector.is_within_box(point1, point2).
I'm obtaining all the vectors I need using playerinfo.get_abs_origin() and saving them in three different variables (location, point1, point2)
Somehow the function location.is_within_box(point1, point2) is always returning false, even if the location is between those two points.
Am I missing something or how does this work?
mathlib's is_within_box()
Works fine for me. What's you test code?
Syntax: Select all
from mathlib import Vector
point0 = Vector()
point1 = Vector(100, 100, 100)
# Prints True
print(Vector(5, 5, 5).is_within_box(point0, point1))
# Prints False
print(Vector(5, 5, 101).is_within_box(point0, point1))
Basically just like this:
Syntax: Select all
# saving player locations earlier (two different locations)
point1 = playerinfo.get_abs_origin()
point2 = playerinfo.get_abs_origin() #point2 is above point1
# getting current player location later
location = playerinfo.get_abs_origin()
# while location is between both points
if location.is_within_box(point1, point2):
return True
# won't return True...
Okay sorry, I thought it would be enough.
In my HUD following was printed:
This should return True, shouldn't it?
Edit:
I found out why it wasn't working for me. When I tested the code and set the two points, the Y coordinate from point1 was bigger than the Y coordinate from point2, so the function would never return True.
But when I set both points so that the Y coordinate from point1 is smaller then the Y coordinate from point2 (like in ayutos example above), the function returns True.
So, from what I understand, the function only returns True if point2.y >= location.y >= point1.y, but shouldn't it return True if point1.y >= location.y >= point2.y as well?
Edit2:
After more testing I had the same problem with the X coordinate when switching point1 and point2 to different corners of the box.
So I made this simple function now, that seems to work very well for me (can be done a lot better I guess):
Maybe you can copy that idea into your code ;)
In my HUD following was printed:
Code: Select all
player 1167 2595 96
point1 1075 2715 96
point2 1249 2544 170
This should return True, shouldn't it?
Syntax: Select all
# Players
from players.entity import PlayerEntity
# Filters
from filters.players import PlayerIter
# Messages
from messages import SayText2
from messages import HintText
# Ticklistener
from listeners import TickListenerManager
# Commands
from commands.say import SayCommandManager
def load():
SayCommandManager.register_filter(say_filter)
TickListenerManager.register_listener(tick_listener)
def unload():
SayCommandManager.unregister_filter(say_filter)
TickListenerManager.unregister_listener(tick_listener)
point1 = None
point2 = None
def say_filter(playerinfo, teamonly, command):
text = command[1]
if text.startswith('!point1'):
point1 = playerinfo.get_abs_origin()
SayText2(message="Set point1 to {0} {1} {2}".format(point1.x, point1.y, point1.z)).send()
elif text.startswith('!point2'):
point2 = playerinfo.get_abs_origin()
SayText2(message="Set point2 to {0} {1} {2}".format(point2.x, point2.y, point2.z)).send()
return True
def tick_listener():
if point1 == None or point2 == None:
return
for index in PlayerIter('alive'):
player = PlayerEntity(index)
playerinfo = player.playerinfo
location = playerinfo.get_abs_origin()
HintText(message="player: {0} {1} {2}\npoint1: {3} {4} {5} \npoint2: {6} {7} {8}".format(
int(location.x), int(location.y), int(location.z), int(point1.x), int(point1.y), int(point1.z),
int(point2.x), int(point2.y), int(point2.z))).send(index)
if location.is_within_box(point1, point2):
SayText2(message="True").send()
Edit:
I found out why it wasn't working for me. When I tested the code and set the two points, the Y coordinate from point1 was bigger than the Y coordinate from point2, so the function would never return True.
But when I set both points so that the Y coordinate from point1 is smaller then the Y coordinate from point2 (like in ayutos example above), the function returns True.
So, from what I understand, the function only returns True if point2.y >= location.y >= point1.y, but shouldn't it return True if point1.y >= location.y >= point2.y as well?
Edit2:
After more testing I had the same problem with the X coordinate when switching point1 and point2 to different corners of the box.
So I made this simple function now, that seems to work very well for me (can be done a lot better I guess):
Syntax: Select all
def is_within_box(loc, point1, point2):
if (point2.x >= loc.x >= point1.x or point1.x >= loc.x >= point2.x) and \
(point2.y >= loc.y >= point1.y or point1.y >= loc.y >= point2.y) and \
point2.z >= loc.z >= point1.z:
return True
Maybe you can copy that idea into your code ;)
I just had a look at the implementation of Vector::WithinAABox(). So, what you found out by testing can be proved by this snippet. Maybe we should add an own implementation of this method instead of using the engine implementation.
However, you can also use this workaround.
Edit: I added this fix to the repo. https://github.com/Source-Python-Dev-Team/Source.Python/commit/d485236a850b04499b153c9cb94ba351bce7f099
Syntax: Select all
bool Vector::WithinAABox( Vector const &boxmin, Vector const &boxmax)
{
return (
( x >= boxmin.x ) && ( x <= boxmax.x) &&
( y >= boxmin.y ) && ( y <= boxmax.y) &&
( z >= boxmin.z ) && ( z <= boxmax.z)
);
}
However, you can also use this workaround.
Syntax: Select all
if location.is_within_box(point1.min(point2), point2.max(point1)):
Edit: I added this fix to the repo. https://github.com/Source-Python-Dev-Team/Source.Python/commit/d485236a850b04499b153c9cb94ba351bce7f099
Return to “Plugin Development Support”
Who is online
Users browsing this forum: No registered users and 124 guests