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: dev-unsubscr...@commons.apache.org
For additional commands, e-mail: dev-h...@commons.apache.org

Reply via email to