Hello.
> >
> > I started to work on the proposed new features, namely convex hull and
> > voronoi diagrams but am a bit stuck with the API design.
> >
> > The current type structure in the geometry package introduced a so
> > called Space with different implementation for 1D, 2D and 3D. To
> > represent a Vector in the respective space, a Vector<S extends Space>
> > interface exists, with implementing classes for each Space:
> >
> > * Vector1D
> > * Vector2D
> > * Vector3D
> >
> > Unfortunately, the Vector interface does not provide a generic access
> > method to each component, e.g. get(int) to get the ith component of the
> > vector. Each subclass has its own getX(), getY() ... method according to
> > the dimension of the Space. This makes it impossible to implement a
> > generic algorithm using the Space as type parameter.
>
> Yes, it would be nice to add a generic getter. In fact, we also thought
> about implementing the whole RealVector methods. This has to be thought
> again since now RealVector is an abstract class.
>
We should be careful not to prevent future flexibility by assuming that a
"Vector" is a Cartesian vector.
I.e. we should not assume that a generic getter "get(int)" will return the
Cartesian coordinates. Maybe that an extended interface would do:
-----
public interface Cartesian<S> extends Vector<S extends Space> {
public double getCartesianCoordinate(int i);
}
-----
> >
> > Ok, so I was thinking about separate algorithms for the different
> > spaces. Now when trying to generify a ConvexHull interface using the
> > Space I would have something like this:
> >
> > public interface ConvexHull<S extends Space> {
> > Vector<S>[] generate(Vector<S>[] points);
> > }
> >
> > e.g. with an implementation of the 2D GrahamScan algorithm:
> >
> > public class GrahamScan2D implements ConvexHull<Euclidean2D> {
> >
> > public Vector<Euclidean2D>[] generate(
> > final Vector<Euclidean2D>[] points) { ... }
> > }
> >
> > So the Vector types would not be Vector2D, Vector3D but the generic
> > ones. Users would need to explicitly cast to them, as I guess these are
> > more convenient to use.
>
> I think you are speaking about what we have already encountered in BSP
> trees. For example the 3D Plane implements the toSpace method from the
> Embedding interface as follows:
>
> public Vector3D toSpace(final Vector<Euclidean2D> point) {
> final Vector2D p2D = (Vector2D) point;
> return new Vector3D(p2D.getX(), u,
> p2D.getY(), v,
> -originOffset, w);
> }
>
> So yes, there is an ugly cast somewhere.
I guess that we could drop the cast (with the new interface):
-----
public Vector3D toSpace(final Cartesian<Euclidean2D> point) {
return new Vector3D(point.getCartesianCoordinate(0), u,
point.getCartesianCoordinate(1), v,
-originOffset, w);
}
-----
>
> >
> > A better solution would be to ignore the Space for now and define the
> > interface as follows:
> >
> > public interface ConvexHull<S extends Space, V extends Vector<S>> {
> > V[] generate(V[] points);
> > }
> >
> > which allows me to use Vector2D and so forth directly in the implementation.
>
> This is interesting.
>
> >
> > Package structure:
> >
> > right now the geometry package is structured as follows:
> >
> > * basic interfaces in the base package
> > * euclidean package split up for the 1D, 2D and 3D cases
> > * partitioning package
> >
> > I started creating a hull package, which will contain the outlined
> > ConvexHull interface, and implementations, for the different Spaces,
> > e.g. GrahamScan2D, DivideAndConquer2D, Chan3D
> >
> > Does this make sense? Or should I stick to the general case and provide
> > only one algorithm for the 2D and 3D respectively?
>
> No, several algorithms are a good thing. I think all of them have their
> pros and cons so they are suited for different problems (accuracy,
> speed, memory requirement, size of data...) and users can choose the
> best one.
Several algorithms, yes; but if they share anything (in principle) they
should be designed so as to avoid code duplication. [Maybe that the
situation is similar to "SimplexOptimizer", where there are two different
strategies for the simplex update ("NelderMead" and "MultiDirectional").]
> >
> > Maybe we should also create an algo package which will serve as home for
> > such algorithms?
>
> This seems too broad a category.
I agree; ultimately almost everything would go in "algo" ;-).
At this point, I don't have a proposal on how to organize those
functionalities.
I'd be wary about creating a mirror of what is under "euclidean" (i.e.
"oned", "twod", etc.); e.g. this would better be avoided:
euclidean/oned
/twod
/threed
hull/oned
/twod
/threed
Ideally, common (non-dimension-specific) algorithms would go under "hull"
and dimension-specific implementations (if needed or useful) would go under
the corresponding sub-packages of "euclidean".
Best regards,
Gilles
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]