Closed WJSchakel closed 6 months ago
Transform2d
is used to perform the transform. It can only accept a Bounds2d
to transform, not more generalized bounds. Although it can transform a single Point2d
or an Iterator<Point2d>
.
To utilize this, we introduce interface TransformableBounds<B extends TransformableBounds<B>>
which defines a B transform(final Transform2d transformation);
method. Bounds of OTS objects can implement this interface to return transformed bounds using the iterator approach. For example in BoundingPolygon
(which wraps a Polygon2d
):
public BoundingPolygon transform(final Transform2d transformation)
{
return new BoundingPolygon(new Polygon2d(transformation.transform(this.polygon.getPoints())));
}
Finally, we introduce abstract class OtsRenderable<L extends Locatable> extends Renderable2d<L>
and overwrite the contains
method. It is highly similar to the super implementation in Renderable2d
, but note the instanceof TransformableBounds<?>
and how the transform is subsequently used.
public boolean contains(final Point2d pointWorldCoordinates, final Bounds2d extent)
{
try
{
if (getSource().getBounds() instanceof TransformableBounds<?> && getSource().getLocation() instanceof Oriented)
{
Point<?> center = getSource().getLocation();
TransformableBounds<?> bounds = (TransformableBounds<?>) getSource().getBounds();
Point2d c = new Point2d(center.getX(), center.getY());
Oriented<?> o = (Oriented<?>) center;
Transform2d transformation = new Transform2d();
transformation.translate(c);
transformation.rotation(o.getDirZ());
return bounds.transform(transformation).contains(pointWorldCoordinates);
}
else
{
return super.contains(pointWorldCoordinates, extent);
}
}
catch (RemoteException ex)
{
CategoryLogger.always().warn(ex, "contains");
return false;
}
}
All OTS classes that extended Renderable2d
now extend OtsRenderable
. It is suggested that DSOL should incorporate similar changes such that more generic bounds can be used.
A much cheaper method is of course to translate the world coordinate, rather than an entire shape:
public boolean contains(final Point2d pointWorldCoordinates, final Bounds2d extent)
{
try
{
if (getSource().getLocation() instanceof Oriented)
{
Point<?> center = getSource().getLocation();
Oriented<?> o = (Oriented<?>) center;
Transform2d transformation = new Transform2d();
transformation.translate(-center.getX(), -center.getY());
transformation.rotation(-o.getDirZ());
Point2d pointObjectCoordinates = transformation.transform(pointWorldCoordinates);
return ((Bounds<?, Point2d, ?>) getSource().getBounds()).contains(pointObjectCoordinates);
}
return super.contains(pointWorldCoordinates, extent);
}
catch (RemoteException ex)
{
CategoryLogger.always().warn(ex, "contains");
return false;
}
}
This then applies to all types of bounds, rendering TransformableBounds
useless.
Tried to get OTS to be consistent with:
This is not yet possible. DSOL does not consider bounds like this. The following was done:
OtsLocatable
which specifies 2d output. Some sub-classes further specify OrientedPoint2d
as location.OtsBounds2d
which defines asPolygon()
and signedDistance(Point2d)
methods.BoundingBox
, BoundingBoxRounded
, BoundingBoxCircle
and BoundingBoxPolygon
. BoundingRectangle
is a sub-class, which exists for places where non-centered bounds must be used (mostly for DSOL).TransformableBounds
.In both animation and the editor, elements are now clickable by their actual bounds. For point and line elements, this entails an additional area of 2m wide.
The method
Renderable2d.contains(...)
usesBoundsUtil.projectBounds(...)
. This has the following line:These box bounds are subsequently used to check whether the clicked coordinate is within it. This makes precise clicking on items quite a hassle.