Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
0
Question by up2004523 · Mar 30 at 03:40 AM · matrix4x4

Multiplying Matrices 4x4 (manually)


EDIT: This is a school project to learn math


Hello everyone. I'm trying to multiply two matrices 4x4. I have a quick question just to confirm if is right what I'm doing.

Is this:

 for (int j = 0; j < rv.values.Length; j++)
 for (int i = 0; i < lhs.values.Length; i++)
 for (int a = 0; a < rhs.values.Length; a++)
 {
     rv.values[0,j] = lhs.values[i, 0] * rhs.values[0, a];
 }

the same as this:

 rv.values[0,0] = lhs.values[0,0] * rhs.values[0,0] + lhs.values[0,1] * rhs.values[1,0] + lhs.values[0,2] * rhs.values[2,0] + lhs.values[0,3] * rhs.values[3,0];
 rv.values[0,1] = lhs.values[1,0] * rhs.values[0,1] + lhs.values[1,1] * rhs.values[1,1] + lhs.values[1,2] * rhs.values[2,1] + lhs.values[1,3] * rhs.values[3,1];
 rv.values[0,2] = lhs.values[2,0] * rhs.values[0,2] + lhs.values[2,1] * rhs.values[1,2] + lhs.values[2,2] * rhs.values[2,2] + lhs.values[2,3] * rhs.values[3,2];
 rv.values[0,3] = lhs.values[3,0] * rhs.values[0,3] + lhs.values[3,1] * rhs.values[1,3] + lhs.values[3,2] * rhs.values[2,3] + lhs.values[3,3] * rhs.values[3,3];


Comment
Add comment · Show 6
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image andrew-lukasik · Mar 29 at 09:02 PM 0
Share

You do realize you can multiply 4x4 matrices with an * operator, right?

 Matrix4x4 rhs = new Matrix4x4(
     column0: new Vector4( 5 , 4 , 3 , 2 ) ,
     column1: new Vector4( 5 , 4 , 3 , 2 ) ,
     column2: new Vector4( 5 , 4 , 3 , 2 ) ,
     column3: new Vector4( 5 , 4 , 3 , 2 )
 );
 Matrix4x4 lhs = new Matrix4x4(
     column0: new Vector4( 5 , 4 , 3 , 2 ) ,
     column1: new Vector4( 5 , 4 , 3 , 2 ) ,
     column2: new Vector4( 5 , 4 , 3 , 2 ) ,
     column3: new Vector4( 5 , 4 , 3 , 2 )
 );
 Matrix4x4 rv = lhs * rhs;

rv:

col0: ( 70 , 56 , 42 , 28 )

col1: ( 70 , 56 , 42 , 28 )

col2: ( 70 , 56 , 42 , 28 )

col3: ( 70 , 56 , 42 , 28 )


avatar image up2004523 andrew-lukasik · Mar 30 at 11:25 AM 0
Share

The matrices don't have any initial value and To multiply matrices you need the dot product of the row of the matrix lhs with each element of the column of matrix rhs so I'm not sure what you're trying to say sorry...

avatar image Captain_Pineapple up2004523 · Mar 30 at 12:27 PM 1
Share

What andrew is trying to say is that he does not understand (same as me) why you are trying to create a manual 3-loop-deep solution to a problem that can be solved in one line.


Judging from your OP you have 2 4x4 Matrizes. These have values as they are value types. If you follow the multiplication rv = lhs * rhs you have your multiplication result which is - as you correctly described - that rv(x,y) is the sum of dot products of the x'th row of lhs with all columns in rhs.

Show more comments

1 Reply

· Add your reply
  • Sort: 
avatar image
1

Answer by Bunny83 · Apr 01 at 03:23 PM

To answer your question directly:

No, your two pieces of code do not do the same thing. Not even close. Also both snippets of code have nothing to do with matrix multiplication.


As andrew already mentioned, Unity's Matrix4x4 struct already has a multiply operator which does already calculate the matrix product for you.


We don't even know what your rv, lhs and rhs variables actually represent (yes, they should represent matrices, however we have no idea about the datatypes and your matrix layout). It looks like your "values" is a two dimensional array or a custom indexer of a class, we don't know. Anyways, what does Length actually return assuming we talk about 4x4 matrices? Does it return 16 or 4? Yes, when you want to create your own matrix class / type, the matrix multiplication is simply that you calculate the dot product between the row vector of the first matrix with the column vector of the second vector. The resulting value is the value for the intersection of those two vectors. So for a 4x4 matrix you need a total of 16 dot products, nothing more, where each dot product requires 4 multiplications and 3 additions. As you can see in the code I've linked above, Unity has actually "unrolled" the code as using two loops would be worse in terms of performance. Using constant values as indices is faster than using a variable.


If, for whatever reason, you want to roll your own matrix type and you want to implement the matrix multiplication yourself in a generic way for arbitrarily sized matrices, yes, you would need 3 loops where the inner most loop would carry out the actual dot product. It's almost impossible to built upon your code since we don't even know if your first index denotes the column or row index.


I quickly wrote this bare minimum general purpose matrix class:

 public class Matrix
 {
     // sticking with Unity's convention of having a column major format.
     // So the first N values represent the first column where N is the number of rows
     public int columns;
     public int rows;
     public float[] values;
     public Matrix(int aRows, int aColumns, bool aSetIdentity = false)
     {
         rows = aRows;
         columns = aColumns;
         values = new float[rows * columns];
         if (aSetIdentity)
         {
             int count = rows;
             if (columns < count)
                 count = columns;
             for (int i = 0; i < count; i++)
                 values[i * (rows + 1)] = 1f;
         }
     }
     public float this[int aRow, int aColumn]
     {
         get => values[aRow + aColumn * rows];
         set => values[aRow + aColumn * rows] = value;
     }
     public static Matrix operator*(Matrix a, Matrix b)
     {
         if (a.columns != b.rows)
             throw new System.Exception("Can't multiply the two matrices, columns of first doesn't match rows of second");
         Matrix r = new Matrix(a.rows, b.columns);
         for(int i = 0; i < r.columns; i++)
         {
             for (int j = 0; j < r.rows; j++)
             {
                 float v = 0f;
                 for (int k = 0; k < a.columns; k++)
                     v += a[j, k] * b[k, i];
                 r[j, i] = v;
             }
         }
         return r;
     }
     public static Matrix Transpose(Matrix aMat)
     {
         Matrix r = new Matrix(aMat.columns, aMat.rows);
         for(int i = 0; i< aMat.columns; i++)
         {
             for (int j = 0; j < aMat.rows; j++)
             {
                 r[i, j] = aMat[j, i];
             }
         }
         return r;
     }
 }

I haven't really tested it, but it should be able to carry out any matrix multiplication you want. You can represent vectors by a 1xN or Nx1 matrix. Keep in mind when you multiply a matrix by a vector, the vector has to be a column vector (so 1 column and N rows). The matrix multiplication works with any compatible matrices, they don't even need to be square. However the number of columns of the first has to match the number of rows of the second. So multiplying a 20x12 matrix with a 12x9 matrix would yield a 20x9 matrix as you would expect. Just to walk through the example, the 3 loops inside the multiply operator would be as following: The outer "i" loop would make 9 iterations(one for each column), the middle loop "j" would make 20 iterations (one for each two). The innermost "k" loop would make 12 iterations since 12 is the number of elements our dot product requires in this case. Of course for a 4x4 matrix they would all make 4 iterations ^^.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

136 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

LookRotation flipping 180 degrees through y axis 1 Answer

How do i get world position of collider if it inside multiple scaled gameobjects? 0 Answers

2d Texture Rotation Problem 1 Answer

Convention of matrices passed to shaders 1 Answer

How to manually calculate localToWorldMatrix/worldToLocalMatrix? 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges