Exemplo n.º 1
0
def OffsetAlong(X, H, Y):
	X = toVector(X, '"X offset along H by Y" with X not a vector')
	Y = toVector(Y, '"X offset along H by Y" with Y not a vector')
	if isinstance(H, VectorField):
		H = H[X]
	H = toHeading(H, '"X offset along H by Y" with H not a heading or vector field')
	return X.offsetRotated(H, Y)
Exemplo n.º 2
0
def RelativeTo(X, Y):
	"""The 'X relative to Y' polymorphic operator.

	Allowed forms:
		F relative to G (with at least one a field, the other a field or heading)
		<vector> relative to <oriented point> (and vice versa)
		<vector> relative to <vector>
		<heading> relative to <heading>
	"""
	xf, yf = isA(X, VectorField), isA(Y, VectorField)
	if xf or yf:
		if xf and yf and X.valueType != Y.valueType:
			raise RuntimeParseError('"X relative to Y" with X, Y fields of different types')
		fieldType = X.valueType if xf else Y.valueType
		error = '"X relative to Y" with field and value of different types'
		def helper(context):
			pos = context.position.toVector()
			xp = X[pos] if xf else toType(X, fieldType, error)
			yp = Y[pos] if yf else toType(Y, fieldType, error)
			return xp + yp
		return DelayedArgument({'position'}, helper)
	else:
		if isinstance(X, OrientedPoint):	# TODO too strict?
			if isinstance(Y, OrientedPoint):
				raise RuntimeParseError('"X relative to Y" with X, Y both oriented points')
			Y = toVector(Y, '"X relative to Y" with X an oriented point but Y not a vector')
			return X.relativize(Y)
		elif isinstance(Y, OrientedPoint):
			X = toVector(X, '"X relative to Y" with Y an oriented point but X not a vector')
			return Y.relativize(X)
		else:
			X = toTypes(X, (Vector, float), '"X relative to Y" with X neither a vector nor scalar')
			Y = toTypes(Y, (Vector, float), '"X relative to Y" with Y neither a vector nor scalar')
			return evaluateRequiringEqualTypes(lambda: X + Y, X, Y,
											   '"X relative to Y" with vector and scalar')
Exemplo n.º 3
0
def RelativeTo(X, Y):
	xf, yf = isA(X, VectorField), isA(Y, VectorField)
	if xf or yf:
		if xf and yf and X.valueType != Y.valueType:
			raise RuntimeParseError('"X relative to Y" with X, Y fields of different types')
		fieldType = X.valueType if xf else Y.valueType
		error = '"X relative to Y" with field and value of different types'
		def helper(context):
			pos = context.position.toVector()
			xp = X[pos] if xf else toType(X, fieldType, error)
			yp = Y[pos] if yf else toType(Y, fieldType, error)
			return xp + yp
		return DelayedArgument({'position'}, helper)
	else:
		if isinstance(X, OrientedPoint):	# TODO too strict?
			if isinstance(Y, OrientedPoint):
				raise RuntimeParseError('"X relative to Y" with X, Y both oriented points')
			Y = toVector(Y, '"X relative to Y" with X an oriented point but Y not a vector')
			return X.relativize(Y)
		elif isinstance(Y, OrientedPoint):
			X = toVector(X, '"X relative to Y" with Y an oriented point but X not a vector')
			return Y.relativize(X)
		else:
			X = toTypes(X, (Vector, float), '"X relative to Y" with X neither a vector nor scalar')
			Y = toTypes(Y, (Vector, float), '"X relative to Y" with Y neither a vector nor scalar')
			return valueRequiringEqualTypes(X + Y, X, Y, '"X relative to Y" with vector and scalar')
Exemplo n.º 4
0
def RelativePosition(X, Y=None):
    """The 'relative position of <vector> [from <vector>]' operator.

	If the 'from <vector>' is omitted, the position of ego is used.
	"""
    X = toVector(X, '"relative position of X from Y" with X not a vector')
    if Y is None:
        Y = ego()
    Y = toVector(Y, '"relative position of X from Y" with Y not a vector')
    return X - Y
Exemplo n.º 5
0
def DistanceFrom(X, Y=None):
    """The 'distance from <vector> [to <vector>]' operator.

	If the 'to <vector>' is omitted, the position of ego is used.
	"""
    X = toVector(X, '"distance from X to Y" with X not a vector')
    if Y is None:
        Y = ego()
    Y = toVector(Y, '"distance from X to Y" with Y not a vector')
    return X.distanceTo(Y)
Exemplo n.º 6
0
def Beyond(pos, offset, fromPt=None):
	pos = toVector(pos, 'specifier "beyond X by Y" with X not a vector')
	dType = underlyingType(offset)
	if dType is float or dType is int:
		offset = Vector(0, offset)
	elif dType is not Vector:
		raise RuntimeParseError('specifier "beyond X by Y" with Y not a number or vector')
	if fromPt is None:
		fromPt = ego()
	fromPt = toVector(fromPt, 'specifier "beyond X by Y from Z" with Z not a vector')
	lineOfSight = fromPt.angleTo(pos)
	return Specifier('position', pos.offsetRotated(lineOfSight, offset))
Exemplo n.º 7
0
def OffsetAlong(X, H, Y):
	"""The 'X offset along H by Y' polymorphic operator.

	Allowed forms:
		<vector> offset along <heading> by <vector>
		<vector> offset along <field> by <vector>
	"""
	X = toVector(X, '"X offset along H by Y" with X not a vector')
	Y = toVector(Y, '"X offset along H by Y" with Y not a vector')
	if isinstance(H, VectorField):
		H = H[X]
	H = toHeading(H, '"X offset along H by Y" with H not a heading or vector field')
	return X.offsetRotated(H, Y)
Exemplo n.º 8
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.position = toVector(self.position,
                              f'"position" of {self} not a vector')
     self.corners = (self.position, )
     self.visibleRegion = CircularRegion(self.position,
                                         self.visibleDistance)
Exemplo n.º 9
0
def ApparentHeading(X, Y=None):
	if not isinstance(X, OrientedPoint):
		raise RuntimeParseError('"apparent heading of X from Y" with X not an OrientedPoint')
	if Y is None:
		Y = ego()
	Y = toVector(Y, '"relative heading of X from Y" with Y not a vector')
	return apparentHeadingAtPoint(X.position, X.heading, Y)
Exemplo n.º 10
0
 def __contains__(self, thing):
     """Check if this `Region` contains an object or vector."""
     from scenic.core.object_types import Object
     if isinstance(thing, Object):
         return self.containsObject(thing)
     vec = toVector(thing, '"X in Y" with X not an Object or a vector')
     return self.containsPoint(vec)
Exemplo n.º 11
0
def ApparentlyFacing(heading, fromPt=None):
	heading = toHeading(heading, 'specifier "apparently facing X" with X not a heading')
	if fromPt is None:
		fromPt = ego()
	fromPt = toVector(fromPt, 'specifier "apparently facing X from Y" with Y not a vector')
	value = lambda self: fromPt.angleTo(self.position) + heading
	return Specifier('heading', DelayedArgument({'position'}, value))
Exemplo n.º 12
0
def CanSee(X, Y):
	if not isinstance(X, Point):
		raise RuntimeParseError('"X can see Y" with X not a Point')
	if isinstance(Y, Object):
		return X.canSee(Y)
	else:
		Y = toVector(Y, '"X can see Y" with Y not a vector')
		return X.visibleRegion.containsPoint(Y)
Exemplo n.º 13
0
def Follow(F, X, D):
	if not isinstance(F, VectorField):
		raise RuntimeParseError('"follow F from X for D" with F not a vector field')
	X = toVector(X, '"follow F from X for D" with X not a vector')
	D = toScalar(D, '"follow F from X for D" with D not a number')
	pos = F.followFrom(X, D)
	heading = F[pos]
	return OrientedPoint(position=pos, heading=heading)
Exemplo n.º 14
0
def OffsetBy(offset):
    """The 'offset by <vector>' specifier.

	Specifies 'position', with no dependencies.
	"""
    offset = toVector(offset, 'specifier "offset by X" with X not a vector')
    pos = RelativeTo(offset, ego()).toVector()
    return Specifier('position', pos)
Exemplo n.º 15
0
def FacingToward(pos):
	"""The 'facing toward <vector>' specifier.

	Specifies 'heading', depending on 'position'.
	"""
	pos = toVector(pos, 'specifier "facing toward X" with X not a vector')
	return Specifier('heading', DelayedArgument({'position'},
												lambda self: self.position.angleTo(pos)))
Exemplo n.º 16
0
    def _specify(self, prop, value):
        assert prop not in self.properties

        # Normalize types of some built-in properties
        if prop == 'position':
            value = toVector(value, f'"position" of {self} not a vector')
        elif prop == 'heading':
            value = toHeading(value, f'"heading" of {self} not a heading')

        self.properties.add(prop)
        object.__setattr__(self, prop, value)
Exemplo n.º 17
0
def ApparentHeading(X, Y=None):
	"""The 'apparent heading of <oriented point> [from <vector>]' operator.

	If the 'from <vector>' is omitted, the position of ego is used.
	"""
	if not isinstance(X, OrientedPoint):
		raise RuntimeParseError('"apparent heading of X from Y" with X not an OrientedPoint')
	if Y is None:
		Y = ego()
	Y = toVector(Y, '"relative heading of X from Y" with Y not a vector')
	return apparentHeadingAtPoint(X.position, X.heading, Y)
Exemplo n.º 18
0
def ApparentlyFacing(heading, fromPt=None):
	"""The 'apparently facing <heading> [from <vector>]' specifier.

	Specifies 'heading', depending on 'position'.

	If the 'from <vector>' is omitted, the position of ego is used.
	"""
	heading = toHeading(heading, 'specifier "apparently facing X" with X not a heading')
	if fromPt is None:
		fromPt = ego()
	fromPt = toVector(fromPt, 'specifier "apparently facing X from Y" with Y not a vector')
	value = lambda self: fromPt.angleTo(self.position) + heading
	return Specifier('heading', DelayedArgument({'position'}, value))
Exemplo n.º 19
0
def Beyond(pos, offset, fromPt=None):
	"""The 'beyond X by Y [from Z]' polymorphic specifier.

	Specifies 'position', with no dependencies.

	Allowed forms:
		beyond <vector> by <number> [from <vector>]
		beyond <vector> by <vector> [from <vector>]

	If the 'from <vector>' is omitted, the position of ego is used.
	"""
	pos = toVector(pos, 'specifier "beyond X by Y" with X not a vector')
	dType = underlyingType(offset)
	if dType is float or dType is int:
		offset = Vector(0, offset)
	elif dType is not Vector:
		raise RuntimeParseError('specifier "beyond X by Y" with Y not a number or vector')
	if fromPt is None:
		fromPt = ego()
	fromPt = toVector(fromPt, 'specifier "beyond X by Y from Z" with Z not a vector')
	lineOfSight = fromPt.angleTo(pos)
	return Specifier('position', pos.offsetRotated(lineOfSight, offset))
Exemplo n.º 20
0
def CanSee(X, Y):
    """The 'X can see Y' polymorphic operator.

	Allowed forms:
		<point> can see <object>
		<point> can see <vector>
	"""
    if not isinstance(X, Point):
        raise RuntimeParseError('"X can see Y" with X not a Point')
    if isinstance(Y, Point):
        return X.canSee(Y)
    else:
        Y = toVector(Y, '"X can see Y" with Y not a vector')
        return X.visibleRegion.containsPoint(Y)
Exemplo n.º 21
0
def leftSpecHelper(syntax, pos, dist, axis, toComponents, makeOffset):
	extras = set()
	if canCoerce(dist, float):
		dx, dy = toComponents(coerce(dist, float))
	elif canCoerce(dist, Vector):
		dx, dy = coerce(dist, Vector)
	else:
		raise RuntimeParseError(f'"{syntax} X by D" with D not a number or vector')
	if isinstance(pos, OrientedPoint):		# TODO too strict?
		val = lambda self: pos.relativize(makeOffset(self, dx, dy))
		new = DelayedArgument({axis}, val)
		extras.add('heading')
	else:
		pos = toVector(pos, f'specifier "{syntax} X" with X not a vector')
		val = lambda self: pos.offsetRotated(self.heading, makeOffset(self, dx, dy))
		new = DelayedArgument({axis, 'heading'}, val)
	return Specifier('position', new, optionals=extras)
Exemplo n.º 22
0
def Following(field, dist, fromPt=None):
	"""The 'following F [from X] for D' specifier.

	Specifies 'position', and optionally 'heading', with no dependencies.

	Allowed forms:
		following <field> [from <vector>] for <number>

	If the 'from <vector>' is omitted, the position of ego is used.
	"""
	if fromPt is None:
		fromPt = ego()
	else:
		dist, fromPt = fromPt, dist
	if not isinstance(field, VectorField):
		raise RuntimeParseError('"following F" specifier with F not a vector field')
	fromPt = toVector(fromPt, '"following F from X for D" with X not a vector')
	dist = toScalar(dist, '"following F for D" with D not a number')
	pos = field.followFrom(fromPt, dist)
	heading = field[pos]
	val = OrientedVector.make(pos, heading)
	return Specifier('position', val, optionals={'heading'})
Exemplo n.º 23
0
def At(pos):
    """The 'at <vector>' specifier.

	Specifies 'position', with no dependencies."""
    pos = toVector(pos, 'specifier "at X" with X not a vector')
    return Specifier('position', pos)
Exemplo n.º 24
0
def AngleFrom(X, Y):
    """The 'angle from <vector> to <vector>' operator."""
    X = toVector(X, '"angle from X to Y" with X not a vector')
    Y = toVector(Y, '"angle from X to Y" with Y not a vector')
    return X.angleTo(Y)
Exemplo n.º 25
0
def AngleTo(X):
    """The 'angle to <vector>' operator (using the position of ego as the reference)."""
    X = toVector(X, '"angle to X" with X not a vector')
    return ego().angleTo(X)
Exemplo n.º 26
0
def AngleFrom(X, Y):
	X = toVector(X, '"angle from X to Y" with X not a vector')
	Y = toVector(Y, '"angle from X to Y" with Y not a vector')
	return X.angleTo(Y)
Exemplo n.º 27
0
def At(pos):
	pos = toVector(pos, 'specifier "at X" with X not a vector')
	return Specifier('position', pos)
Exemplo n.º 28
0
def FieldAt(X, Y):
    """The '<VectorField> at <vector>' operator."""
    if not isinstance(X, VectorField):
        raise RuntimeParseError('"X at Y" with X not a vector field')
    Y = toVector(Y, '"X at Y" with Y not a vector')
    return X[Y]
Exemplo n.º 29
0
def OffsetBy(offset):
	offset = toVector(offset, 'specifier "offset by X" with X not a vector')
	pos = RelativeTo(offset, ego()).toVector()
	return Specifier('position', pos)
Exemplo n.º 30
0
def FacingToward(pos):
	pos = toVector(pos, 'specifier "facing toward X" with X not a vector')
	return Specifier('heading', DelayedArgument({'position'},
	                                            lambda self: self.position.angleTo(pos)))