shall a vector2 extends a vector3 or is it the opposite?

Perhaps the question might be tied to a theoritical or mathematical forum, but since it is for programming purpose, i ask here first:

In a computer vision context, i write a couple of interfaces intended to be the “read-only” part of vectors. So i define “IVector2R” and “IVector3R” that only contain getters. The question is:
does IVector2R extends IVector3R (and the “y getter” always returns 0), or is it the opposite: IVector3R extends IVector2R?

I would like a conception as close as possible to the mathematic/sets theory…

Thank you for your attention

3

I would like a conception as close as possible to the mathematic/sets theory…

When you work with vector coordinates, it means that you work in some vector space where you chose a base. Asking if there is a natural relation between 2-dimensional vectors and 3-dimensional vectors is the same thing as as asking if there is a natural relation between a 2-dimensional vector space equipped with a base and a 3-dimensional vector space equipped with a base. In general, there is not.

However, it seems you are working with a euclidean space with a basis (e1, e2, e3) so that the vector of coordinates (X,Y,Z) is Xe1 + Ye2 + Ze3. If you assume that your 2-dimensional space has the basis (e1,e2) then you have two natural maps between 2-dimensional vectors and 3-dimensional vectors:

- The projection (X,Y,Z) -> (X,Y)
- The embedding (X,Y) -> (X,Y,0)

Therefore, from a mathematical point of view, there is no natural way to express a relation between 2-dimensional vectors and 3-dimensional vectors that you could express through inheritance. There is however two natural transformations that you could implement as regular functions.

In my opinion, neither nor: Both are n-tuples with different n. The problem with this is that most languages don’t allow types to be parameterized by a value.

When deciding a certain inheritance, you should consider matrix multiplication.

/1 0   /2 ?  /1 0 0   /2
 1/ · |3| =  |0 1 0| · 3/
        4/     0 0/

You are implicitly arguing that one or both multiplications work (and should possibly be equivalent). At this point every mathematician is having a heart attack, because you violated certain rules about the required dimensionality.

I think it is obvious that Vector3 can’t be a subtype of Vector2, and not the other way round: You cannot generally use one in place of the other. But both have common properties. I would probably define an interface Vector with methods like component(i) which gives the i-th component (instead of getX, getY, …), size() which gives the dimensionality, and norm() which calculates the length.

If you are hell-bent on having one type inheriting from another, consider these test cases:

// failure with Vector3 <: Vector2 -- vec.z can be != 0
if (vec instanceof Vector2)
  assert vec.z == 0;

// failure with Vector3 <: Vector2 -- vec.z can be != 0
if (vec instanceof Vector2)
  assert vec.norm() == sqrt(vec.x^2 + vec.y^2); // euclidean norm - invalid in non-cartesian systems

// failure with Vector2 <: Vector3 if they are mutable (Circle-Ellipse Problem)
if (vec instanceof Vector2) {
  vec.z = 42;
  assert vec.z == 0;
}

// failures concerning dimensionality with *any* inheritance relation
// when considering matrix multiplication

This means that I have to grudgingly admit that having Vector2 inherit from Vector3 would work in most cases, if they are immutable and you aren’t doing anything more fancy than addition or scalar multiplication.

Note On Coordinates

If you don’t want to do vector algebra but just want to represent coordinates, then this answer would be different, because 2D coordinates can be viewed as a projection of 3D coordinates into a plane (or any other surface parameterizable by two numbers). In this case, every 2D coordinate would also have a 3D coordinate, but the two coordinates are from two different coordinate systems. Projection into the z = 0-plane is one very special case of this where it is possible to view the 2D-coordinate as a kind of 3D-coordinate. This is not generally the case in all 2D coordinate systems.

2

Interesting.

From the Liskov Substitution Principle, one could argue that a Vector3R “is a” Vector2R, but just with more stuff (a Z axis if these are dimensions, a “y getter” in your vision example). I think from a “purist” math/sets POV this works best. The drawback is that your class hierarchy might get messy, with eventual Vector4R, SomeSpecialVector3R, ImmutableVector3R, etc…

So, arguing that a Vector2R is a Vector3R but always returns 0 (or null, etc.) makes a bit of sense too. And it might make your class hierarchy much less messy. For example, you don’t even need a Vector2R class. Perhaps just an additional method, whatIsMyN().

Option#2 is how Java handles it’s Collections – instead of a gazillion classes in a dense hierarchy, they are allowed to say “no” by returning 0 (actually, in their case, they do even worse, throw an exception). Some programmers like it, and some hate it. Drawback: It requires that your code be a bit smarter: either ask ahead of time if this “Vector3” has a y getter, or be prepared for and ready to deal with 0s coming back.

I’ve coded both ways. Depends how “reasonable” it is, in your domain, for 0s to be coming back.

1

Please define what methods or operations Vector2R and Vector3R have in common and the use case where you’d want to treat them the same without needing to know which is which. Those would be reasons to come up with a common interface. Failing that, there is no useful answer to your question.

I’m presuming matrix multiplication is your use case? “Vector” and “Array” are loaded terms in some languages. In Java they are the same, but in Scala, Vector=shallow tree. In JavaScript, Array=Map/Dictionary. Even in math and physics, “Vector” can mean many things.

Otherwise, “Favor Composition Over Inheritance.” But I’ll give you some background information.

Most languages have multidimensional arrays built in:

  • Java
  • Scala
  • Clojure
  • Haskell

Matrix Multiplication can be done in most languages as well:

  • Clojure’s core.matrix
  • Scala/Haskell
  • Many other languages – this may be what you were looking for – not sure…

So most languages side-step your issues or provide no support for abstracting over n dimensions where n can change. This is why your use case is critical for designing a meaningful abstraction for treating arrays of different dimensions as the same.

So finally, I simplify by only declaring a IMatrixR interface. I let the implementation doing more “optimized” stuff with specific classes such as Vector3 or Vector4, both implementing the IMatrixR interface.

But at a generic level, the UML diagram becomes a little bit more tricky to draw since there is more constraints to indicate and a set of exceptions (or error code to return) to specify on each methods; those implying conditions that i would rather automatically avoid by the type checking process during compilation.

As an example, the mul(IMatrixR,IMatrixR) method has to raise an exception when the dimensions are not compatible. But the overloading method mul(Matrix4,Vector4) will never throw it! Whereas the standard implementation of mul(IMatrixR,IMatrixR) does. The overloading method will be more efficient and does not require to be surrounded by try/catch…

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật