-
-
Notifications
You must be signed in to change notification settings - Fork 3.5k
p5.Matrix made public #7754
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Input is welcome on criteria to make |
Hi @ksen0 👋, I would like to tackle this issue, From what I understand, the main goal is to make I’m thinking of working on refactoring it to a more general location (like => Which files should I focus on for making the Matrix class public and usable? Thanks in Advance 😊 |
Hi all! I think it might help for us to start with a bit of context on what's been done, as well as a list of next steps. As I'll explain below, I think the top priority is to get a better idea of the feature set, and then to work on the API. Sorry this post is so long. I have a lot to say, apparently 😅 But I do hope that this post will be helpful! @Mamatha1718 Hello! 👋 You can take a look at the current code that @ksen0 shared, if you'd like. (These features are in Note: I've been involved in the discussions but haven't worked on this part of the code myself, so I'll ping some of the other contributors in case I'm missing anything important. Current state of p5.MatrixI just reviewed some previous discussions related to matrix features and extensions of p5's math features generally, going back to 2021: #5210, #6527, and #6765. My sense is that there was rough consensus of support for a few things:
I think @limzykenneth may be able to confirm or correct me on that summary of past discussions. Since then, my understanding is that @holomorfo has done the following:
Taking a step back, the recent proposals for the math features in 2.0 were much broader, so a lot of the discussion wasn't directly related to matrices. In particular, I don't think there was a ton of discussion on the problems solved by exposing matrices, the desired feature set, or the API. I think those discussions are still needed (mainly around the features and API). Motivation: What problems does
|
3x3 | 4x4 |
---|---|
![]() |
![]() |
Proposed next step: Refine the feature set
Internally, p5's matrix features were designed for very specific purposes in computer graphics. But, as discussed above, the overall context of p5 may call for a more general feature set.
The main data structure (or data structures)
I think there are some design constraints that I'm not totally aware of; @davepagurek may have a better idea. But, my own current feeling is that the data structure that makes the most sense for p5 is a general
Some reasons:
- Reusability There are plenty of instances when working with data and visualizing it calls for rectangular matrices. Want to visualize two planes in three dimensions? No problem. Want to visualize the intersection of those planes? A user might try using a rectangular matrix for that.
-
Consistency Students who study matrices in math classes won't generally assume matrices are square. Also if we put
p5.Matrix
in the math module alongside the now n-dimensionalp5.Vector
objects in 2.0, as I think we should, users will won't expect the possible dimensions to be bounded to 2, 3, or 4. If we put these two expectations together, we get rectangular matrices. All this makes it easier for users to work with high-dimensional data. -
Not too special, not too general For the core of p5, I'm guessing that a more general data structure, like the tensors @nickmcintyre developed for número, might be a bit overwhelming for a lot of users (I'm not sure, though). In any case, I'd hope we could design a general matrix class so that it could be easily extended to a tensor class, or at least so that its API could be extended seamlessly? If we can successfully design
p5.Matrix
so that it effectively works as an extension ofp5.Vector
, then maybe a tensor class could extendp5.Matrix
in the same way? I haven't thought about the details here. As an example, we might treat matrix-vector multiplication the same way whether a vector is represented as an$n \times 1$ matrix or an$n$ -dimensionalp5.Vector
instance.
The main operations
I wonder if it might be beneficial to have some kind of separation between general math features and specialized features for graphics? Maybe not. But if so, how? It's all fundamentally math, but there seems to be a fairly natural separation. (The feature list below is rough, but I think it gets the general idea across.)
Math
- Reading and writing
- convert matrix to nested array
- convert nested array to matrix
- set a new matrix using an old matrix
- get, set general submatrices (possibly w/ convenience functions for rows, cols,
$1 \times 1$ submatrices)1 - get, set diagonal elements if that's helpful
- set/reset to identity matrix, maybe zero matrix
- Arithmetic
- add (
$m \times n$ +$m \times n$ ) - multiply (possibly with overloads as in two.js)
- determinant (
$n \times n$ ) - trace (
$n \times n$ ) (could maybe omit, but may be expected if determinant is supported) - transpose (
$m \times n$ ) - inverse (
$n \times n$ invertible matrices)
- add (
- Algebra
- linear-system solving, with least-squares solution when appropriate (requires discussion)2
Graphics
- normal matrix (convenience feature based on submatrix, transpose, inverse features?)
- setters (convenience features based on general setter feature)
- set rotation matrix 3
- Input: angle, and optionally, an axis when applicable
- Option or mode for number of spatial dimensions, and for linear or affine?
- Could consider further convenience functions for specifically rotating about coordinate axes
- set scaling matrix (uniform or non-uniform, i.e. each coordinate axis gets its own scale factor)
- set translation
- set perspective matrix
- set orthographic projection matrix
- set rotation matrix 3
Separation strategy: If it makes sense to separate these types of features (I'm not sure yet if it does), we might consider naming conventions, or simply different submodule names for a logical separation in the reference, or... probably not different classes I guess, right?
Phase strategy: Alternatively, we might only expose general math features to start, since those would be more reusable (in particular, they'd be sufficient for recreating all the graphics functions), since they're arguably necessary for consistency with
API
I have a list of questions/ideas about the current p5.Matrix
API, but I think it may be good if we can get a better sense of the feature set first. For now, some general questions and design considerations:
- Mutate or return new objects? Or both, but distinguished with a naming convention? Where did we come down on this?
- Want interoperability with other libraries if possible.
- To what extent might we be bound by a need to be consistent with
applyMatrix()
? If we want more flexibility, what workarounds might there be? (For example, specifying matrices with flat arrays may not be the most intuitive for general math usage.)
Inspiration
For now, I'm just parking this fairly random and not-meant-to-be-exhaustive-or-representative list of existing libraries here. I figure we might take design inspiration from it. I may come back and add more or annotate it more, if it looks like it might be helpful. I collected some of these from the old discussions, but I didn't try to list everything. If anyone wants me to add anything, just let me know.
- Mostly graphics focused (small matrices)
- Mostly data focused (tensors)
- stdlib ndarray
- TensorFlow.js
- número (builds on TensorFlow.js)
- ml5.js (builds on TensorFlow.js)
- ndarray library (seems to be abandoned, but worth a look)
- numjs (builds on ndarray, not actively developed)
- math.js discussion about matrix redesign
- math.js matrices (multidimensional)
- Mostly math focused (general matrices)
- Multi-focus
- babylon.js (graphics focused, but provides tensors, matrices, vectors)
Updates:
- Added trace to the proposed feature set, for consideration.
- Added linear-system solving (with least squares when appropriate), for consideration, per suggestion from @davepagurek.
- Added to list of sources for inspiration.
Footnotes
-
Subsets of matrix elements (rather than submatrices) might be useful for some purposes, but I'm guessing that might be too much for the core of p5. ↩
-
It'd probably make sense to only include a version of MATLAB's
A \ B
, notA / B
. The latter is used infrequently and could be obtained by combiningA \ B
andA'
, where the latter denotes the transpose operation, viaB/A = (A'\B')'
. See MATLAB's documentation of linear-system solving, and their documentation forA \ B
for inspiration. ↩ -
For anyone who's curious and knows some math but not much graphics, or vice versa, you might find these Wikipedia explanations helpful: the article on rotation matrices, a coordinate-wise explanation of affine transformations and projective transformations, and a a block-matrix explanation of affine transformations ↩
Just a little extra info to frame the discussion: although WebGL is primarily the current user of For separating general math/graphics applications: in broader math, matrices are a very general tool, while in graphics there is a specific way of interpreting the data that may not apply in the general case. Some examples:
My 2 cents is that it's not worth trying to generalize those methods to work across the board. I think the use case is less clear as you generalize those (even though it's still valid), and it's more easily explained when we can have the specific graphics use case built-in. Additionally, we may need a different implementation for the graphics ones to keep them fast. So a possible way forward could be:
|
For naming, I'm currently thinking the graphics-specific one could be called something like |
Hi team, I also want to add my two cents since I've been working on the Matrix revamp since last year. I feel that there are two main directions here:
These two are not necessarily compatible, since having (nxm)-dimentional operations in a performant way is a challenging issue. In this direction, the request was to explore if we could implement other Matrix impelmentations that would help us. I created an initial As a next step we should have a generic implementation of nxm matrices, however the challenge is to still be compatible with the existing render API. So the greatest challenge is to make this render performant AND flexible and compatible. I agree with Dave that we might need to have an internal optimized In this new didactic I would like to continue this effort or collaborate with whoever might be working on it since its really tricky to do the modifications while not breaking existing functionality and maybe I can provide some insight. Thanks |
@davepagurek , @holomorfo , @GregStanton Thanks for the clarification! I checked Also, I noticed most methods like |
Hi all! There's a lot to chew on here. I'll share some thoughts about what's been discussed so far. I'm trying out collapsed-section formatting instead of headings so that the details don't clog up our discussion. Also, I've edited this comment a fair amount since publishing it, just FYI; I didn't make a log of my edits since it doesn't look like anyone has read it yet. Generality@davepagurek Thanks for all your great ideas! I agree that we don't need to generalize the graphics-specific features to higher dimensions. Also, to summarize the conversation so far, it looks like there's an initial consensus around supporting rectangular matrices (at least among the participants so far).Linear-system solving (and trace)I added linear-system solving to the potential-feature list in my previous comment, as well as trace (I omitted a trace feature originally since we could maybe get by without it, but I think it's natural to predict that trace would be supported if determinant is, so I added it for consideration).I think linear-system solving could make a lot of sense for the core of p5:
Follow-up considerations:
Naming (general vs. graphics features)Assuming we end up having separate classes for general matrix features and specialized graphics features...
I like "TransformationMatrix"! It’ll be familiar to users, and it’s accurate: mathematically, a "transformation matrix" can represent linear, affine, and projective transformations, all of which p5 uses. In fact, the Wikipedia article of the same name covers all three. I don't think it's too general or vague either: although all of p5’s matrices could be thought of as transformations, I think the graphics versions are the only ones we’d refer to as transformations in the reference, and the only ones that are intentionally interpreted as transformations. The name is a little long, but I’m not too worried about that; it's probably better to avoid abbreviations, and that'd be consistent with other p5 names like A shorter alternative that doesn't rely on abbreviations is Basic vs. augmented matricesWhen I mentioned "linear" vs. "affine," I had a somewhat different idea in mind. I'll try to explain it here for anyone following along. Since "affine" will be unfamiliar to most p5 users, I'll also discuss simpler terminology at the end.We can represent any linear transformation from ![]() To represent a linear transformation like a rotation, we can let the translation vector b equal the zero vector. In general, the matrix A and the corresponding augmented matrix when ![]() (The components of Now, if I talk to a linear algebra student about rotation matrices, they're going to think of the
I was thinking there could be dedicated methods for creating both of types of matrices via the “graphics”/"transformation matrix" interface. The user would just supply an angle, and if appropriate, an axis. They'd also need to specify the dimension in some way (e.g. with a mode, a method argument, or a dedicated method). Although @davepagurek mentioned supporting just If we support both the basic and augmented transformations on a But, I think the first thing is to decide whether we want the "basic" versions at all. We could consider what other libraries do, but I think that for p5, supporting both might make sense? Another option would be to support only the augmented versions, since it'd still be possible to implement the basic versions by setting matrices manually via DesignDocumenting design challenges@holomorfo:I would like to continue this effort or collaborate with whoever might be working on it since its really tricky to do the modifications while not breaking existing functionality and maybe I can provide some insight. Glad you’re going to continue with this! Do you think you might be able to summarize with bullet points why it’s tricky to change things without breaking them? Those pain points might either suggest opportunities for improvement, or if not, they might give us a better sense of the design constraints. A list of examples, or if it’s easier, some general types of challenges, would probably be really helpful. Overall designHow might we separate general and graphics features, at a high level? How might we want shared features to be shared? What design patterns make sense? Would CRC cards be helpful here?So far, we've discussed having separate Phasing/hidingAssuming we separate the general and graphics features into different classes, would it make sense to expose the general matrix class first? Would we definitely want to expose the performant graphics version later?My initial thinking is that it would still make sense to expose both, although possibly in stages to be a little safer. Exposing the graphics version would force us to clean it up and make things better for contributors, it'd help p5 users advance and learn more about graphics, and it’d probably make it easier for add-on contributors to reuse the same functionality (e.g. maybe they want to allow transforms inside custom coordinate systems, or if they're working on an animation feature, they might want to repeatedly apply graphics transformations to an individual shape rather than the entire coordinate system...). But, as noted above, it wouldn't be quite as important to expose both classes if If the general and graphics interfaces are well designed, I think there will be a clear enough logical separation for users, and their interfaces will be similar enough that learning one will make it easy to learn the other. Edit: Revised comment regarding matrix inverses. |
Hi @Mamatha1718 thanks for your interest, but as you mentioned, there is still a lot of discussion ongoing, so it might make sense to check back in later/periodically or look for issues that are marked ready for work if you're interested in getting started with implementation. Thanks for all the rigorous discussion @holomorfo @GregStanton @davepagurek ! Here's a proposed breakdown of implementation steps that I feel are still consistent with the intent and leave some room for discussion:
I think each of these are separate PRs / possibly separate issues. Importantly, I think both 1 and 2 are well-defined given what's already there, but 3 is a major topic, so I think it would be productive to keep that one a bit separated. I'm assigning this issue to @holomorfo for clarity, but of course the discussion and work can be distributed! @GregStanton noted:
My 2 cents here is that exposing the graphics matrix first is strongly preferable because that is the primary current use-case, there's a lot of performance work that's been done, and the main things preventing |
@ksen0 , Thanks for the clarification! I understand that things are still evolving. I’ll keep an eye on the discussions and look out for issues marked “ready for work.” |
Increasing access
The access statement covers technical maintenance and improvements in the following way:
Making
p5.Matrix
available for both general andWEBGL
use can support beginners who are using p5.js to encounter and learn mathematical concepts, which are important to many creative coding practices.Most appropriate sub-area of p5.js?
Feature enhancement details
p5.Matrix
is currently a private class that is used extensively forWEBGL
and provides some general-purpose math functions. The goal is to make it public in a way that supports beginners to both graphics usage and mathematics more generally.The text was updated successfully, but these errors were encountered: