dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.06k stars 4.69k forks source link

Add primitive structs Rectangle and Point #13999

Closed lilith closed 4 years ago

lilith commented 9 years ago

System.Drawing, System.Windows, and XNA all implement nearly-identical structures to represent points and rectangles.

Given the verbosity of a correct implementation, many library developers re-use an existing implementation, and tie their public APIs to (non-core-compatible) dependencies.

Offering primitives like Point, Rectangle (as well as PointF, RectangleF, and Color) would make it much easier for libraries to be compatible with each other.

Or, is there a de-facto standard nuget package for these structs that we can promote?

mikedn commented 9 years ago

You forgot WinRT's own Point & co. This inevitable reminds me of http://xkcd.com/927/

colombod commented 9 years ago

That has been my dream since 2005 to see geometry and drawing structures unified, I think it would be great if there was a namespace to provide geometric and mathematic object and function. The only problem is that some kind of backward compatibility has to be put in place unless both winforms and wpf (including RT flavours) are unified in all api requiring points, colours, vectors, rectangles and all other stuff. What are your ideas?

Dr Diego Colombo PhD

On 21 Jan 2015, at 07:45, mikedn notifications@github.com wrote:

You forgot WinRT's own Point & co. This inevitable reminds me of http://xkcd.com/927/

— Reply to this email directly or view it on GitHub.

ebickle commented 9 years ago

At some point the CoreFx project is going to reach System.Drawing, which takes a hard dependency on GDI+. Not easily portable, and many of the patterns used in that library aren't a great fit for current needs.

Rather than bake this directly into an existing corefx library, I wonder whether this would be a good fit for a new API layered on two. One assembly for the common geometry types, written in a similar manner to the new vector library. Another assembly for the actual graphics imaging. Adding drawing support is a lot tougher, but my vote would be to try to keep the drawing and imaging (file format) logic as independent as possible.

It's also worth pointing out that in my own projects, I make use of integer geometry types quite a bit. I imagine that the use cases for integer types and floating point types are likely equally balanced.

mikedn commented 9 years ago

@ebickle "At some point the CoreFx project is going to reach System.Drawing, which takes a hard dependency on GDI+. "

Nope, System.Drawing isn't part of .NET Core.

ebickle commented 9 years ago

@mikedn Exactly. Perfect candidate for a new API or community project.

colombod commented 9 years ago

I think that the main point is to split the model (algebraic functions) from the rendering/graphics implementation. They usually requires different kind of "native support". Jit and intrinsics will play a central role in all vector operations and convolution operators ( here a lot of cool stuff can be done to offload to Opencl, have a look at fscl project on GitHub). The vector graphics and other could both use DX and OpenGL, today most of the heavy lifting is around data transfer and shader programs. Really looking forward to see if coreFx could finally bring a common ground for algebra and geometry based computation with truly cross platform models and decoupled from graphics systems (gdi+, DX, wpf, OpenGL and the likes)=

colombod commented 9 years ago

Would be nice to find a "place" to discuss the ideas you guys have and try to shape the api/framework, do you have any suggestion? Skype meeting or any other idea?=

ebickle commented 9 years ago

@colombod No suggestions, but definitely open to a discussion. Might not be a bad corefxlab project, System.Numerics.Geometry or something along those lines.

System.Numerics.Geometry.Rectangle System.Numerics.Geometry.Point2 System.Numerics.Geometry.Point3 System.Numerics.Geometry.Point4 System.Numerics.Geometry.Ray 3+ dimensional rectangle types (BoundingBox, etc)

There's a large number of geometric shapes and operations. We'll strong a strong use case to define the need and logical boundary for the API. Might not be a bad idea to wait to hear back from the corefx team - this is probably something that's been discussed internally at Microsoft many times as well.

Potential issues include:

colombod commented 9 years ago

I am totally in! My suggestion about what type to support would be based on what types can be efficiently used (specially via intrinsics). Most of the currently available data structures were made as easy or ad hoc bridge for underlying graphics systems without much support for relevant functions (distance functions or convolution for example). I have done a few (or at least contributed) as I am coming from video games development background where such object are a little bit more important than mere data for graphics systems. Usually supported formats are from 16 to 32 bit but numerical libraries should provide high precision stuff. In C++ I always looked at things like blitz++ for it gives powerful optimisations to geometry algorithms.

I suggest we focus on set of primitives and methods (distance, intersection, etc..) and we aim to come up not only with some classes but with a design that is consistent and easy to extend with space and precision changes (as you mentioned a rectangle can be express in different ways and they serve some methods better then others).

I am really looking forward to work on something like that. As per personal "inside experience" with WPF and XNA design I'd suggest we start with no dependencies and we ask the lovey guys of the CLR to have a little review and plan to see how coreFX types and this "objects" should relate to introduce

1) unified geometric and algebraic model 2) a fresh starting point for future extensions with performance as good as OOB types (XNA was pretty frustrating when defining custom vectors.....) 3) mathematically consistent 4) beyond ninja 5) easy to adopt so to spawn interests from all those R and Python users that are writing data crunching algs

I am really looking forward to be part of such a project!!!

KrzysztofCwalina commented 9 years ago

I think it would be great to experiment with something like that, but I have to tell you this must be the hardest project you could pick up. :-)

I have participated in many design groups trying to unify such types and it seems like it's very hard to design such one unified set that would work reasonably well for many scenarios.

Also, I am not sure how such types could be used by existing APIs without often forcing them to introduce breaking changes. Would this be just for new projects?

Lastly, I think such types should be designed in a context of some larger set of graphics related projects, not in a vacuum. Do we have any such projects that would like take dependency on such unified graphics abstractions?

colombod commented 9 years ago

I have been giving this some more —brain time—. What made .NET an incredible platform is the fact that its core (type system and virtual machine) where born on a white board, TPL, WCF, WPF and all the rest came later. Adoption was the key!

My humble view here is that we should produce a clear road map and split the definition from functionalities. It should be something built with the relevant layers and structure; that can make it easy to integrate and adopt in different scenarios.

As has been stated already there are different ways of define the exactly same rectangle, each is more appropriate when used in specific scenarios and context (rendering vs containment for example).

A key feature should be that a representation should be able to be translate in any other according to the use case.

If there was a good definition of primitives it would be easy to adopt them in computational application as well in rendering (raster, vector or 3D) with complete interoperability.

That means that a a float4 could be immediately consumed as colour object in a shader, in WPF and in a computer vision algorithm as well in machine learning.

To come up with a solid design of a core system and a clear road map for development, extension, integration and porting would build a solid base for adoption that can really make all this work a widely adopted convention.

Plugging different functionality on top would be a piece of cake and could make a great difference.

Think twice and cut once (or not cut at all) is the best approach and it is important to align this to coreFX phylosophy because once adopted a poor design would introduce breaking changes and be the death of such initiative.

What are your thoughts? =

KrzysztofCwalina commented 9 years ago

I think it would be worth doing analysis of the requirements, prototype the some straw man unified APIs and measure whether translating between existing values and the unified values is reasonable (e.g. from performance perspective). In other words, I think it's worth doing a proof of concept, given you feel passionate about it.

colombod commented 9 years ago

Life thought me that the model is king, performance will follow :)

xanather commented 9 years ago

I was thinking about such a unified library before! Glad discussion about it has already begun. If other libraries such as SharpDX and OpenTK both use the same Math/primitive struct library then that would be awesome. Having to maintain use multiple "Math" libraries that do the same thing depending on the framework your developing can be somewhat redundant.

We need stuff like Matrix, Vector2 (or would we use the System.Numerics version? - could just be a wrapper), Vector3 etc, and precomputed Shadow Matrix within it too.

Edit: SharpDX is already moving away from having its own seperate Math object library and OpenTK seems open to supporting .NET Core and the System.Numerics. OpenTK currently uses the System.Drawing namespace which wouldn't work on .NET Core, this library could fill the gap for it. Both are good timing for such a math library.

colombod commented 9 years ago

Great, so we are not alone:) the key I think is to also split definition from function and not fall into the graphic domain immediately, but make it a layer of api built on top.

Dr Diego Colombo PhD

On 30 Jan 2015, at 18:03, Jordan Singh notifications@github.com wrote:

I was thinking about such a unified library before! Glad discussion about it has already begun. If other libraries such as SharpDX and OpenTK both use the same Math/primitive struct library then that would be awesome. Having to maintain use multiple "Math" libraries that do the same thing depending on the framework your developing can be somewhat redundant.

We need stuff like Matrix, Vector2 (or would we use the System.Numerics version? - could just be a wrapper), Vector3 etc, and precomputed Shadow Matrix within it too.

— Reply to this email directly or view it on GitHub.

KrzysztofCwalina commented 9 years ago

@colombod, so is anybody working on a concrete proposal? If not, I will close this issue.

colombod commented 9 years ago

Going over some sketch just got snowed in new job. Will post soon a proposed architecture and see if someone jumps on as well.

akoeplinger commented 9 years ago

This seems related to https://github.com/dotnet/corefx/issues/1563

colombod commented 9 years ago

Looks similar but here the discussion was going over more general primitive support. Colours can be implemented on top of other structures and there have been many implementations. Not entirely bought on the conversion as exposed. HSL encoding should be its own type. Would love an implementation were conversions and unpacking is performed more like the active pattern matching of F#. Some example with coordinate space translations are really good and make more sense than properties to retrieve encoded/decoded values (like the H property on the colour exposed in the item you refer to)

KrzysztofCwalina commented 9 years ago

dotnet/corefx#1563 had a discussion on this and we decided to do this library in corefxlab.