Nếu một vectơ 3D đại diện cho một điểm, làm thế nào nó có thể có chiều dài?


27

Tôi đang cố gắng để hiểu số học vectơ (và cụ thể là việc sử dụng nó trong công cụ Unity). Tôi không thể tìm ra làm thế nào một vectơ có thể có chiều dài (độ lớn) mặc dù nó chỉ đại diện cho một điểm (vị trí và hướng)?

Điều đó có nghĩa là độ lớn chỉ đơn giản là khoảng cách của nó so với điểm gốc (0, 0, 0)? Hay tôi đang thiếu một cái gì đó?


14
Hãy xem xét một vô hướng, còn được gọi là một số. Nó có thể có nghĩa là một giá trị tuyệt đối, một sự khác biệt, một tỷ lệ phần trăm, v.v.
Peter

1
Normalizedtrong ngữ cảnh có nghĩa là một vectơ mới bảo tồn Directionnhưng có Magnitude1. Nghĩa là Normalizedvectơ được tạo bằng cách chia tỷ lệ vectơ gốc.
Theraot

@Theraot, Cảm ơn bạn rất nhiều, câu đó đã giúp tôi rất nhiều!
Mohammed Noureldin

19
Nó không. Nó đại diện cho một sự dịch chuyển. Nó chỉ trỏ đến một số điểm nếu bạn coi nó là một vectơ vị trí , trong trường hợp đó nó biểu thị sự dịch chuyển từ (0, 0, 0). Độ dài của một vectơ vị trí như vậy là khoảng cách của điểm đến điểm gốc.
Polygnome

1
@Peter Tôi sợ tôi phải không đồng ý với bạn. Các định nghĩa đại số tiêu chuẩn của một vectơ khá nhiều có nghĩa là nó không phải là một điểm. thường rất hữu ích khi xem xét nó như vậy vì các vectơ vị trí có thể được sử dụng để biểu diễn các điểm, nhưng chúng không phải các điểm. "5 mét" luôn là một khoảng cách (hoặc chiều dài), nó sẽ không bao giờ là thời gian hay màu sắc. Việc sử dụng các ký hiệu khác nhau thường rất hữu ích - Cá nhân tôi sẽ không bao giờ sử dụng (5, 5, 5) để biểu thị một vectơ , tôi luôn sử dụng (5, 5, 5) ^ T (T để chuyển đổi) hoặc sử dụng biểu diễn cột thích hợp nơi được hỗ trợ. Bởi vì nói một vectơ một điểm giới thiệu không chính xác.
Polygnome

Câu trả lời:


20

Điều đó có nghĩa là cường độ chỉ đơn giản là khoảng cách từ điểm gốc (0, 0, 0)?

Các tl; dr câu trả lời có thể là: Có, bạn có thể tưởng tượng nó như thế.

Nhưng tôi không chắc liệu điều này có thể không dẫn đến một sự hiểu lầm.


Một vectơ không phải là một điểm, và có một sự khác biệt quan trọng giữa hai!

Việc một vectơ thường được biểu diễn dưới dạng "mũi tên" có thể gây ấn tượng sai. Trên thực tế, một vectơ không phải là một mũi tên. Sẽ chính xác hơn để nói rằng một vectơ là tập hợp của tất cả các mũi tên có cùng chiều dài và hướng . (Mũi tên thường được vẽ chỉ là một đại diện cho tất cả các mũi tên này). Nhưng tôi không muốn đi quá sâu vào các chi tiết nhàm chán của toán học ở đây.

Quan trọng hơn, có một sự khác biệt quan trọng giữa một điểm và một vectơ, điều này trở nên rõ ràng trong lập trình đồ họa khi bạn biến đổi điểm hoặc vectơ. Tôi không quen thuộc với Unity, nhưng từ cái nhìn nhanh vào tài liệu, họ đang mô hình hóa sự khác biệt quan trọng nhất giữa một điểm và một vectơ trong Matrix4x4lớp. Nó có hai chức năng khác nhau:

Sự khác biệt là, đại khái là, một vectơ không được dịch, trong khi một điểm là. Hãy tưởng tượng ma trận 4 x 4 sau đây:

1.0   0.0   0.0   1.0
0.0   1.0   0.0   2.0
0.0   0.0   1.0   3.0
0.0   0.0   0.0   1.0

Nó mô tả một bản dịch về (1,2,3). Bây giờ, khi bạn có mã giả sau đây

Vector3 tp = matrix.MultiplyPoint (new Vector3(2,3,4));
Vector3 tv = matrix.MultiplyVector(new Vector3(2,3,4));

Sau đó tpsẽ là (3,4,5), máy ảnh tvvẫn sẽ là (2,3,4). Dịch một vectơ không thay đổi nó (bởi vì, như đã đề cập ở trên, nó là tập hợp của tất cả các mũi tên có cùng độ lớn và hướng).


Việc Unity sử dụng Vector3lớp cho cả hai, vectơ cho các điểm, là hợp pháp, nhưng có thể gây nhầm lẫn. Các thư viện khác dành riêng biệt giữa Point3DVector3D, đôi khi với một cơ sở chung như thế nào Tuple3D.


3
Bạn có chắc rằng một vectơ là tập hợp của tất cả các mũi tên có cùng độ dài và hướng mà ý nghĩa về mặt toán học không? Âm thanh như bạn đang nói về một số lớp tương đương, nhưng không gian vectơ không phải là thứ tôi từng đọc được định nghĩa là các lớp tương đương. - Bất cứ điều gì, bạn nâng cao một điều rất quan trọng ... e hèm, điểm , với sự khác biệt giữa các không gian vector và không gian afin , đó là những tên toán học cho các loại của tất cả các vectơ / của tất cả các điểm, tương ứng.
rẽ trái

3
A vector is, in fact, not a single arrow, bạn đã đúng, đại diện cho Vector3 như một mũi tên duy nhất chính xác là điều làm tôi bối rối. +1 để đề cập đến câu quan trọng này.
Mohammed Noureldin

@leftaroundabout Có nhiều định nghĩa khác nhau cho các vectơ (ngoài việc là "một số n-tuple ..." hoặc như vậy). Trong đại số tuyến tính, hãy tưởng tượng tập hợp của tất cả các mũi tên và mối quan hệ (tương đương! -) "Có cùng độ dài và hướng". Hệ số hóa tất cả các mũi tên theo quan hệ này mang lại các lớp tương đương. Tôi không muốn viết về những kẻ gièm pha toán học (tôi cũng không phải là nhà toán học), nhưng hy vọng làm rõ rằng một vectơ không phải là "một mũi tên bắt đầu từ (0,0,0)". Điểm (...) là: Một vectơ không có "vị trí".
Marco13

2
Nó thậm chí còn phức tạp hơn bởi khoa học máy tính sử dụng thuật ngữ này vectorcó nghĩa là mảng hoặc nhiều! Trong C ++, bạn có thể có một std::vector<Vector3>ví dụ. A vectorcủa Vectors.
dùng1118321

À, ý của bạn là, bắt đầu từ một không gian affine X , bạn xác định cho hai điểm bất kỳ ( p , q ) một mũi tên sA ( X ) là đường đi ngắn nhất (nghĩa là hàm phân biệt với đạo hàm tuyệt đối tích hợp tối thiểu) s : [0,1] → X sao cho s (0) = p s (1) = q . Sau đó, không gian của vectơ là tập hợp các lớp tương đương Một ( X ) / ~ nơi s ~ σ nếu ∂ s / ∂ t = ∂ σ/ T với mọi t ∈] 0,1 [? Điều đó có ý nghĩa, mặc dù tôi không nghĩ bạn có thể sử dụng điều này như một định nghĩa về vectơ vì sự khác biệt đã phụ thuộc vào chúng.
rẽ trái

36

Điều đó có nghĩa là cường độ chỉ đơn giản là khoảng cách từ điểm gốc (0, 0, 0)?

Chính xác là như vậy.

Trong số những thứ khác, một vectơ có thể đại diện cho một điểm (một vị trí), một hướng và / hoặc vận tốc, tùy thuộc vào bối cảnh.

Nếu bạn có biến này:

Vector3 mPosition;

Nó thường chỉ đại diện cho vị trí, tức là vị trí của nó trong không gian 3d.

Nếu bạn có biến này:

Vector3 mDirection;

Nó thường đại diện cho hướng. Thông thường, các vectơ này là các vectơ đơn vị, tức là vectơ có độ dài 1 (nhưng không phải lúc nào cũng cần thiết). Một vectơ đơn vị và một vectơ chuẩn hóa là như nhau, chúng đều có chiều dài 1. Các vectơ này thường được sử dụng với các vectơ khác để thay đổi vị trí của chúng.

Khi bình thường hóa một vectơ, bạn mất chiều dài (độ lớn của nó), nhưng hướng vẫn giữ nguyên. Có những tình huống khi bạn chỉ cần hướng (ví dụ: khi bạn muốn di chuyển một đối tượng theo hướng đó) và có độ lớn (không dài đơn vị) trong vectơ sẽ đưa ra kết quả tính toán bất ngờ.

Nếu bạn cần một vectơ bình thường cho một phép tính, bạn có thể sử dụng myVec3.normalized , nó sẽ không ảnh hưởng myVec3và nếu bạn có ý định sử dụng vectơ chuẩn hóa đó thường xuyên, có lẽ bạn nên tạo một biến:

Vector3 myVec3Normalized = myVec3.normalized;

để tránh các cuộc gọi lặp lại normalizedphương thức.

Và nếu bạn thấy các biến:

Vector3 mVelocity;

Nó thường đại diện cho một lực / tốc độ: các vectơ này đại diện cho một hướng độ lớn của chúng (chiều dài của chúng) là quan trọng. Họ cũng có thể được đại diện với Vector3 mDirection;và a float mSpeed;.

Tất cả những thứ này được sử dụng liên quan đến nguồn gốc địa phương của chúng, có thể là (0, 0, 0) hoặc có thể là một Vị trí khác.


4
Nó phá hủy một phần thông tin chứa trong vectơ và thông tin đó là độ lớn. Hướng vẫn giữ nguyên tuy nhiên.

6
@Eldy Chính xác hơn là cần lưu ý rằng myVec3.normalizedtrả về Vector3 mới , có cùng hướng nhưng cường độ 1. myVec3không thay đổi
Caleth

4
@ NPSF3000 Đó sẽ là một kẻ ngốc và một người nhảy , không có sự đồng thuận nào về những cái tên vượt quá điều đó. Tất cả chúng ta đều vui mừng khi không phải là phổ biến.
Theraot

1
@ NPSF3000 Một số gợi ý các dẫn xuất thứ 4, 5 và 6 của vị trí nên là snap, crackle và pop! :-D en.wikipedia.org/wiki/Snap,_Crackle_and_Pop#Physics
gbmhunter

1
Có thể thay đổi these vector are unit vectorsđể direction vectors are unit vectorshoặc một cái gì đó? Bởi vì như bây giờ người đọc có thể bị nhầm lẫn khi nghĩ theseđến cả hai ví dụ trước mPosition mDirection . (Đó là cách tôi đọc nó lúc đầu.)
Supr

8

Điều đó có nghĩa là cường độ chỉ đơn giản là khoảng cách từ điểm gốc (0, 0, 0)?

Bạn có thể thấy nó theo cách đó, nhưng chỉ nhìn thấy nó theo cách đó có thể dẫn đến một sự hiểu biết sai lầm.


Trước hết, một vectơ không phải là một điểm và một điểm không phải là một vectơ.

Sự khác biệt giữa một vectơ và một điểm giống như giữa thời lượngthời gian trong ngày . Cái trước là một khoảng thời gian, cái sau là một điểm duy nhất trong thời gian. Rõ ràng là 6 giờ không giống như 6 giờ. Bạn sẽ không nói "Cuộc đua kéo dài 1 giờ" và bạn cũng sẽ không nói "Hãy gặp nhau lúc 13 giờ". Cuộc đua kéo dài một giờ - một khoảng thời gian - và bạn gặp nhau lúc 13 giờ - một thời điểm cụ thể.

Điều tương tự áp dụng cho vectơ và điểm. Một vectơ là một intervall - một sự dịch chuyển nếu bạn muốn. Nó chỉ theo một hướng nhất định, và vâng, nó có chiều dài.

Do đó, điểm và vectơ có liên quan với nhau, giống như thời lượng và thời gian trong ngày. Cuộc đua bắt đầu lúc 13 giờ và kết thúc lúc 15 giờ. Cả hai đều là điểm trong thời gian. Nhưng 15 giờ - 13 giờ = 2 giờ, thời lượng. Cuộc đua kéo dài hai giờ, không phải 2 giờ.

Áp dụng tương tự cho các điểm. Sự khác biệt giữa điểm A và B được ký hiệu là v = B - A, trong đó v biểu thị một vectơ và A và B biểu thị các điểm.

Bây giờ, có một cái gì đó gọi là vectơ vị trí . Bạn có thể coi một vectơ một điểm đến một mức độ nhất định, khi bạn nói rằng các vectơ chỉ từ điểm gốc đến một điểm khác. Nói cách khác: Nếu tất cả bạn bè của bạn biết rằng bạn gọi thời gian trong ngày là thời lượng kể từ nửa đêm (0 giờ), bạn có thể nói "Chúng tôi gặp nhau lúc 6 giờ". Họ sẽ biết rằng 0 giờ + 6 giờ = 6 giờ và do đó, khi nào gặp bạn. Đây là thực tế những gì thời hải quân làm. "Chúng tôi gặp nhau vào lúc sáu giờ rưỡi" có nghĩa là 6 giờ.

Vì vậy, vectơ <1,2,3> trỏ đến điểm (1,2,3), nếu bạn xem điểm gốc là điểm neo và vâng, độ dài của vectơ này là khoảng cách của điểm đó so với điểm gốc.

Nhưng vector <1,2,3> cũng điểm (1,1,1) đến (2,3,4), và trong trường hợp đó chiều dài của nó biểu thị khoảng cách giữa những hai điểm.


Vì vậy, như bạn có thể thấy một vectơ có độ dài bởi vì nó không phải là một điểm, mà là một khoảng - một sự dịch chuyển.


Đọc liên quan: Torsors
Buster

5

Một vectơ có thể biểu thị một đường giữa hai điểm trong không gian 3d (hướng và khoảng cách) hoặc một vị trí trong không gian 3d (chiều dài là khoảng cách từ điểm gốc).

Nếu bạn có điểm A và điểm B, thì BA = AB = hướng và khoảng cách bạn sẽ phải đi để đi từ A đến B.


Cảm ơn bạn, nhưng sau đó nó có nghĩa gì khi sử dụng Vector3. Chuẩn hóa? tài liệu nói:, Returns this vector with a magnitude of 1vậy không phá hủy thông tin được lưu trong vectơ sao? thực sự đó MagnitudeNormalizedlà những gì làm cho tôi bối rối.
Mohammed Noureldin

Cho dù đó là một điểm trong không gian hay một mũi tên biểu thị vận tốc đều nằm trong đầu bạn. Dữ liệu giống nhau đại diện cho cả hai.
Omnifarious

@MohammedNoureldin Một vectơ chuẩn hóa là một trong các đơn vị độ dài (là 1). Có, nếu bạn bình thường hóa một vectơ, bạn sẽ mất thông tin về độ dài hoặc độ lớn. Nếu bạn cần cả hai (hữu ích trong nhiều trường hợp), bạn sẽ có được độ dài của vectơ, sau đó chuẩn hóa nó.
Ian Young

1

Những gì Unity nói về điểm so với vectơ về lâu dài là vô nghĩa, bởi vì API hình học chỉ chọn các định nghĩa riêng biệt để làm cho công cụ dễ truy cập hơn, chúng không tương ứng với cách những thứ này được khái niệm hóa trong hình học. Hãy xem việc triển khai các lớp, nếu bạn có thể. Bởi vì nó tùy tiện, để biết định nghĩa của nó là cách duy nhất để hiểu khái niệm này là gì. Tiết lộ đầy đủ, tôi không có kinh nghiệm về Unity.

Vectơ là một điểm trong không gian vectơ , trong đó khái niệm điểm trong hình học được mã hóa bởi các phần tử của tập hợp bên dưới. Một không gian vectơ có một vectơ phân biệt, được gọi là gốc hoặc 0 . Đại số tuyến tính là một nỗ lực để mã hóa một đoạn hình học euclide với nguồn gốc đại số.

Mũi tên và chiều dài của nó

Chuyển động trên một không gian các điểm thường được hiểu là tất cả các mũi tên từ nguồn / trước các điểm đến mục tiêu / sau các điểm của chúng.

Một hàm của hai đối số có thể được áp dụng cho một đối số để tạo ra hàm của một đối số - chúng ta có thể nói về x +, hàm đưa mỗi vectơ y vào vectơ x + y . Đây là bản dịch liên quan đến w / thêm x . Các mũi tên liên quan chạy từ điểm y đến điểm x + y . Xem: ứng dụng một phần , cà ri .

Vậy tại sao chúng ta chỉ sử dụng một mũi tên ? Mũi tên từ điểm gốc đến một vectơ cụ thể, x trong x + - gốc là danh tính của phép cộng vector. Vì vậy, chúng ta có thể khôi phục bản dịch x + từ giá trị của nó x +0 = x .

Là một biểu diễn đồ họa của không gian, biểu diễn mũi tên phải thực hiện với khả năng của chúng ta để ngoại suy trực quan hoặc vật lý hiệu ứng của bản dịch từ giá trị xác định nó. Khi nào chúng ta có khả năng đó?

Để cung cấp cho không gian vectơ một quy tắc làm cho nó trở thành một không gian vectơ chuẩn là cung cấp một khái niệm về độ dài của vectơ có nghĩa là khoảng cách của nó từ 0. Đồng thời, đây là một khoảng cách thỏa mãn bất đẳng thức tam giác, đó là một ràng buộc mạnh mẽ về độ dài của hai vectơ liên quan đến độ dài của tổng của chúng. Từ chiều dài, chúng ta có thể xác định khoảng cách để biến đây thành một không gian số liệutrắc địa là một con đường thực chất đi thẳng vào đó càng ngắn càng tốt. Các đề Ơclit gây ra khoảng cách Euclide và trắc địa là những đoạn thẳng của các mũi tên, nhưng nếu bạn vẽ các mũi tên như trắc địa sử dụng các chuẩn mực khác nhau, bạn có thể ngoại suy hiệu ứng hình học của bản dịch từ trắc địa để tìm hiểu về hình học.

Ý nghĩa của điểm và vectơ

Trong một số trường hợp khi thực hiện trò chơi hình học, không gian điểm của bạn không phải là không gian vectơ . Một không gian affine của chiều n có thể được nhúng vào một không gian chiếu của chiều n . Bản đồ affine giảm đến dự án. Dự án cũng cho phép bạn làm FOV, w / c tôi nghĩ là không có liên quan. Dự án có lợi ích:

Không gian n chiếu trên một trường có thể được xây dựng từ không gian tuyến tính ( n +1) (không gian vectơ), bằng cách coi các điểm của không gian chiếu là các đường xuyên qua gốc của không gian tuyến tính. Các mặt phẳng qua điểm gốc lần lượt đưa ra các đường chiếu. Nhân vectơ với một ma trận cố định là một bản đồ tuyến tính , đây là những gì nhân ma trận dành cho. Bản đồ tuyến tính bảo tồn nguồn gốc và tương thích với tỷ lệ mắc. Cụ thể, nếu f là một biến dạng tự động tuyến tính ( tương ứng với ma trận khả nghịch ( n +1) x ( n +1)) và hai dòng L, M qua gốc tọa độ một mặt phẳng A , thìf L, f Mlà các dòng thông qua gốc tọa độ f A , vì vậy f cũng sẽ bảo toàn tỷ lệ trên không gian chiếu - một ma trận khả nghịch có tính phóng xạ liên quan. Phép nhân ma trận mã hóa thành phần của các bản đồ tuyến tính, và do đó là các dự án.

Loại bỏ điểm gốc khỏi không gian tuyến tính, tất cả các điểm trên một đường nhất định thông qua điểm gốc là bội số vô hướng của nhau. Khai thác thực tế này, quá trình đồng nhất hóa chọn một điểm tuyến tính để thay thế cho từng điểm chiếu và một ma trận khả nghịch để thay thế cho mỗi chuyển đổi phóng xạ (như trong bản đồ affine 2D -> 2D này dưới dạng video bản đồ tuyến tính 3D -> 3D ), như vậy cách mà các đại diện được đóng dưới các sản phẩm ma trận và ma trận-ma trận và cho và được đưa ra bởi những thứ phóng chiếu độc đáo. Mô tả về việc xây dựng mặt phẳng chiếu từ mặt phẳng tuyến tính liên kết một số thứ với nhau.

Vì vậy, trong đường ống ma trận chiếu mô hình-khung nhìn, chúng ta đang sử dụng các vectơ để biểu thị các điểm của không gian chiếu của chúng ta, nhưng không gian chiếu không phải là một không gian vectơ và không phải tất cả các vectơ trong không gian vectơ mà chúng ta đang sử dụng đại diện cho các điểm hình học của chúng tôi (xem hình ảnh của mặt phẳng affine ở bên phải ). Chúng tôi sử dụng ma trận dịch thay vì tổng vector nếu chúng tôi muốn dịch. Đôi khi, mọi người gọi các vectơ điểm chiếu hoặc affine, đặc biệt là khi sử dụng một thiết lập trong tĩnh mạch này.


2
+1. Nhưng cảm giác ruột của tôi là hầu hết những người hiểu ngôn ngữ bạn đang sử dụng đều đã biết câu trả lời cho câu hỏi ban đầu, vì vậy tôi khuyên bạn nên điều chỉnh câu trả lời cho những người đọc bình thường.
Peter

@Peter Tôi thấy khó khăn để giải quyết mọi thứ. Tôi muốn làm cho nó dễ tiếp cận hơn, nhưng không biết làm thế nào mà không cần giải thích. Tuy nhiên, khi tôi lần đầu tiên làm việc với OpenGL, tôi đã tự hỏi về ý nghĩa của ma trận đồng nhất, ma trận phối cảnh và cách ma trận dịch được phát hiện như một cách thay thế cho bản dịch bằng cách tóm tắt, vì vậy có thể điều này không đi quá sâu. Chủ nghĩa hình thức là ngôn ngữ, và đưa ra các cụm từ đúng, tôi nghĩ làm thế nào để thảo luận về các khái niệm sẽ đi qua. Tuy nhiên, nó rất mờ để được súc tích, vì vậy đây giống như một danh sách đọc Wiki.
Đồng hồ Loki

Tôi đã thêm một số liên kết, đặc biệt là một video về các bản đồ affine đang được thực hiện ở chiều cao hơn dưới dạng bản đồ tuyến tính. Hy vọng rằng sẽ giúp.
Đồng hồ Loki

tốt đẹp. xứng đáng được nâng cao hơn.
Peter

-1

Độ dài (hoặc độ lớn) của vectơ là square root of (x*x+y*y+z*z). Các vectơ luôn được coi là một tia đi từ gốc của điểm <0,0,0> đi qua điểm được mô tả trong vectơ<x,y,z>

Các tài liệu thống nhất về điều này được tìm thấy ở đây .


Xin lỗi, nhưng điều này là hoàn toàn sai. Nếu tôi có hai điểm A và B, thì v = BA là vectơ đi từ A đến B. v hoàn toàn không đi qua gốc tọa độ trong trường hợp này. Một vectơ không phải là một điểm. nó có thể được sử dụng để biểu diễn một điểm (như vectơ vị trí), nhưng nó một cái gì đó khác nhau. Xin vui lòng nhận được những điều cơ bản đại số thẳng.
Polygnome

Tôi đã cập nhật câu trả lời để loại bỏ sự nhầm lẫn, nhưng tôi đang cung cấp tài liệu tham khảo cho tài liệu về Vector3 là gì trong Unity và câu trả lời của tôi phù hợp với tất cả các câu trả lời được xếp hạng cao hơn bao gồm cả câu trả lời của bạn.
Stephan

Nếu bạn đọc tài liệu thống nhất một cách cẩn thận, bạn sẽ nhận thấy rằng nó không bao giờ đề cập đến nguồn gốc, bởi vì nguồn gốc không liên quan gì đến độ dài của vectơ. Vectơ giữa (1,1,1) và (2,3,4) là <1,2,3> và có độ dài sqrt (1 ^ 2 + 2 ^ 2 + 3 ^ 3) = ~ 3.9, trong đó là khoảng cách giữa hai điểm đó. Nó thậm chí không bao giờ chạm vào nguồn gốc ở tất cả . Tôi bối rối như thế nào bạn có thể có thể nghĩ rằng câu trả lời của tôi đồng ý với bạn, bởi vì nó không, ở tất cả .
Polygnome
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.