├── .gitignore
├── LICENSE
├── README.md
├── src
├── LitMath.csproj
├── LitMath.sln
├── LitMath
│ ├── Circle2.cs
│ ├── Line2.cs
│ ├── Matrix3.cs
│ ├── Matrix4.cs
│ ├── Quaternion.cs
│ ├── Rectangle2.cs
│ ├── Utils.cs
│ ├── Vector2.cs
│ ├── Vector3.cs
│ └── ViewUtils.cs
└── Properties
│ └── AssemblyInfo.cs
└── test
├── Program.cs
├── Properties
└── AssemblyInfo.cs
└── Test.csproj
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # MSTest test Results
33 | [Tt]est[Rr]esult*/
34 | [Bb]uild[Ll]og.*
35 |
36 | # NUNIT
37 | *.VisualState.xml
38 | TestResult.xml
39 |
40 | # Build Results of an ATL Project
41 | [Dd]ebugPS/
42 | [Rr]eleasePS/
43 | dlldata.c
44 |
45 | # .NET Core
46 | project.lock.json
47 | project.fragment.lock.json
48 | artifacts/
49 | **/Properties/launchSettings.json
50 |
51 | *_i.c
52 | *_p.c
53 | *_i.h
54 | *.ilk
55 | *.meta
56 | *.obj
57 | *.pch
58 | *.pdb
59 | *.pgc
60 | *.pgd
61 | *.rsp
62 | *.sbr
63 | *.tlb
64 | *.tli
65 | *.tlh
66 | *.tmp
67 | *.tmp_proj
68 | *.log
69 | *.vspscc
70 | *.vssscc
71 | .builds
72 | *.pidb
73 | *.svclog
74 | *.scc
75 |
76 | # Chutzpah Test files
77 | _Chutzpah*
78 |
79 | # Visual C++ cache files
80 | ipch/
81 | *.aps
82 | *.ncb
83 | *.opendb
84 | *.opensdf
85 | *.sdf
86 | *.cachefile
87 | *.VC.db
88 | *.VC.VC.opendb
89 |
90 | # Visual Studio profiler
91 | *.psess
92 | *.vsp
93 | *.vspx
94 | *.sap
95 |
96 | # TFS 2012 Local Workspace
97 | $tf/
98 |
99 | # Guidance Automation Toolkit
100 | *.gpState
101 |
102 | # ReSharper is a .NET coding add-in
103 | _ReSharper*/
104 | *.[Rr]e[Ss]harper
105 | *.DotSettings.user
106 |
107 | # JustCode is a .NET coding add-in
108 | .JustCode
109 |
110 | # TeamCity is a build add-in
111 | _TeamCity*
112 |
113 | # DotCover is a Code Coverage Tool
114 | *.dotCover
115 |
116 | # Visual Studio code coverage results
117 | *.coverage
118 | *.coveragexml
119 |
120 | # NCrunch
121 | _NCrunch_*
122 | .*crunch*.local.xml
123 | nCrunchTemp_*
124 |
125 | # MightyMoose
126 | *.mm.*
127 | AutoTest.Net/
128 |
129 | # Web workbench (sass)
130 | .sass-cache/
131 |
132 | # Installshield output folder
133 | [Ee]xpress/
134 |
135 | # DocProject is a documentation generator add-in
136 | DocProject/buildhelp/
137 | DocProject/Help/*.HxT
138 | DocProject/Help/*.HxC
139 | DocProject/Help/*.hhc
140 | DocProject/Help/*.hhk
141 | DocProject/Help/*.hhp
142 | DocProject/Help/Html2
143 | DocProject/Help/html
144 |
145 | # Click-Once directory
146 | publish/
147 |
148 | # Publish Web Output
149 | *.[Pp]ublish.xml
150 | *.azurePubxml
151 | # TODO: Comment the next line if you want to checkin your web deploy settings
152 | # but database connection strings (with potential passwords) will be unencrypted
153 | *.pubxml
154 | *.publishproj
155 |
156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
157 | # checkin your Azure Web App publish settings, but sensitive information contained
158 | # in these scripts will be unencrypted
159 | PublishScripts/
160 |
161 | # NuGet Packages
162 | *.nupkg
163 | # The packages folder can be ignored because of Package Restore
164 | **/packages/*
165 | # except build/, which is used as an MSBuild target.
166 | !**/packages/build/
167 | # Uncomment if necessary however generally it will be regenerated when needed
168 | #!**/packages/repositories.config
169 | # NuGet v3's project.json files produces more ignorable files
170 | *.nuget.props
171 | *.nuget.targets
172 |
173 | # Microsoft Azure Build Output
174 | csx/
175 | *.build.csdef
176 |
177 | # Microsoft Azure Emulator
178 | ecf/
179 | rcf/
180 |
181 | # Windows Store app package directories and files
182 | AppPackages/
183 | BundleArtifacts/
184 | Package.StoreAssociation.xml
185 | _pkginfo.txt
186 |
187 | # Visual Studio cache files
188 | # files ending in .cache can be ignored
189 | *.[Cc]ache
190 | # but keep track of directories ending in .cache
191 | !*.[Cc]ache/
192 |
193 | # Others
194 | ClientBin/
195 | ~$*
196 | *~
197 | *.dbmdl
198 | *.dbproj.schemaview
199 | *.jfm
200 | *.pfx
201 | *.publishsettings
202 | orleans.codegen.cs
203 |
204 | # Since there are multiple workflows, uncomment next line to ignore bower_components
205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
206 | #bower_components/
207 |
208 | # RIA/Silverlight projects
209 | Generated_Code/
210 |
211 | # Backup & report files from converting an old project file
212 | # to a newer Visual Studio version. Backup files are not needed,
213 | # because we have git ;-)
214 | _UpgradeReport_Files/
215 | Backup*/
216 | UpgradeLog*.XML
217 | UpgradeLog*.htm
218 |
219 | # SQL Server files
220 | *.mdf
221 | *.ldf
222 | *.ndf
223 |
224 | # Business Intelligence projects
225 | *.rdl.data
226 | *.bim.layout
227 | *.bim_*.settings
228 |
229 | # Microsoft Fakes
230 | FakesAssemblies/
231 |
232 | # GhostDoc plugin setting file
233 | *.GhostDoc.xml
234 |
235 | # Node.js Tools for Visual Studio
236 | .ntvs_analysis.dat
237 | node_modules/
238 |
239 | # Typescript v1 declaration files
240 | typings/
241 |
242 | # Visual Studio 6 build log
243 | *.plg
244 |
245 | # Visual Studio 6 workspace options file
246 | *.opt
247 |
248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
249 | *.vbw
250 |
251 | # Visual Studio LightSwitch build output
252 | **/*.HTMLClient/GeneratedArtifacts
253 | **/*.DesktopClient/GeneratedArtifacts
254 | **/*.DesktopClient/ModelManifest.xml
255 | **/*.Server/GeneratedArtifacts
256 | **/*.Server/ModelManifest.xml
257 | _Pvt_Extensions
258 |
259 | # Paket dependency manager
260 | .paket/paket.exe
261 | paket-files/
262 |
263 | # FAKE - F# Make
264 | .fake/
265 |
266 | # JetBrains Rider
267 | .idea/
268 | *.sln.iml
269 |
270 | # CodeRush
271 | .cr/
272 |
273 | # Python Tools for Visual Studio (PTVS)
274 | __pycache__/
275 | *.pyc
276 |
277 | # Cake - Uncomment if you are using it
278 | # tools/**
279 | # !tools/packages.config
280 |
281 | # Telerik's JustMock configuration file
282 | *.jmconfig
283 |
284 | # BizTalk build output
285 | *.btp.cs
286 | *.btm.cs
287 | *.odx.cs
288 | *.xsd.cs
289 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Hisin Wang
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LitMath
2 | A simple 2D and 3D math library for C#
3 | # License
4 | MIT
5 |
--------------------------------------------------------------------------------
/src/LitMath.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}
9 | Library
10 | Properties
11 | LitMath
12 | LitMath
13 | v2.0
14 | 512
15 |
16 |
17 | true
18 | full
19 | false
20 | ..\bin\Debug\
21 | DEBUG;TRACE
22 | prompt
23 | 4
24 |
25 |
26 | pdbonly
27 | true
28 | ..\bin\Release\
29 | TRACE
30 | prompt
31 | 4
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
59 |
--------------------------------------------------------------------------------
/src/LitMath.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 11.00
3 | # Visual Studio 2010
4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LitMath", "LitMath.csproj", "{5C1D6D42-A59E-4A42-84B0-F444E63736DF}"
5 | EndProject
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "..\test\Test.csproj", "{35D3E59A-F22F-4F75-8F65-C296EAFC7703}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Debug|Mixed Platforms = Debug|Mixed Platforms
12 | Debug|x86 = Debug|x86
13 | Release|Any CPU = Release|Any CPU
14 | Release|Mixed Platforms = Release|Mixed Platforms
15 | Release|x86 = Release|x86
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
21 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
22 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Debug|x86.ActiveCfg = Debug|Any CPU
23 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
24 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Release|Any CPU.Build.0 = Release|Any CPU
25 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
26 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Release|Mixed Platforms.Build.0 = Release|Any CPU
27 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}.Release|x86.ActiveCfg = Release|Any CPU
28 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Debug|Any CPU.ActiveCfg = Debug|x86
29 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
30 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Debug|Mixed Platforms.Build.0 = Debug|x86
31 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Debug|x86.ActiveCfg = Debug|x86
32 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Debug|x86.Build.0 = Debug|x86
33 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Release|Any CPU.ActiveCfg = Release|x86
34 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Release|Mixed Platforms.ActiveCfg = Release|x86
35 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Release|Mixed Platforms.Build.0 = Release|x86
36 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Release|x86.ActiveCfg = Release|x86
37 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}.Release|x86.Build.0 = Release|x86
38 | EndGlobalSection
39 | GlobalSection(SolutionProperties) = preSolution
40 | HideSolutionNode = FALSE
41 | EndGlobalSection
42 | EndGlobal
43 |
--------------------------------------------------------------------------------
/src/LitMath/Circle2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LitMath
4 | {
5 | public struct Circle2
6 | {
7 | public Vector2 center;
8 | public double radius;
9 |
10 | public double diameter
11 | {
12 | get { return radius * 2; }
13 | }
14 |
15 | public Circle2(Vector2 center, double radius)
16 | {
17 | this.center = center;
18 | this.radius = radius;
19 | }
20 |
21 | public override string ToString()
22 | {
23 | return string.Format("Circle2(({0}, {1}), {2})",
24 | this.center.x, this.center.y, this.radius);
25 | }
26 |
27 | ///
28 | /// 求通过3点的圆
29 | /// http://blog.csdn.net/liyuanbhu/article/details/52891868
30 | ///
31 | public static Circle2 From3Points(Vector2 pnt1, Vector2 pnt2, Vector2 pnt3)
32 | {
33 | Circle2 circle = new Circle2();
34 |
35 | double a = pnt1.x - pnt2.x;
36 | double b = pnt1.y - pnt2.y;
37 | double c = pnt1.x - pnt3.x;
38 | double d = pnt1.y - pnt3.y;
39 | double e = (pnt1.x * pnt1.x - pnt2.x * pnt2.x + pnt1.y * pnt1.y - pnt2.y * pnt2.y) / 2.0;
40 | double f = (pnt1.x * pnt1.x - pnt3.x * pnt3.x + pnt1.y * pnt1.y - pnt3.y * pnt3.y) / 2.0;
41 | double det = b * c - a * d;
42 |
43 | if (Math.Abs(det) < Utils.EPSILON)
44 | {
45 | circle.center = new Vector2(0, 0);
46 | circle.radius = -1;
47 | }
48 |
49 | circle.center.x = -(d * e - b * f) / det;
50 | circle.center.y = -(a * f - c * e) / det;
51 | circle.radius = Math.Sqrt(
52 | (pnt1.x - circle.center.x) * (pnt1.x - circle.center.x)
53 | + (pnt1.y - circle.center.y) * (pnt1.y - circle.center.y));
54 |
55 | return circle;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/LitMath/Line2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LitMath
4 | {
5 | public struct Line2
6 | {
7 | public Vector2 startPoint;
8 | public Vector2 endPoint;
9 |
10 | public Line2(Vector2 startPnt, Vector2 endPnt)
11 | {
12 | this.startPoint = startPnt;
13 | this.endPoint = endPnt;
14 | }
15 |
16 | public Vector2 centerPoint
17 | {
18 | get
19 | {
20 | return new Vector2(
21 | (this.startPoint.x + this.endPoint.x) / 2.0,
22 | (this.startPoint.y + this.endPoint.y) / 2.0);
23 | }
24 | }
25 |
26 | public Vector2 direction
27 | {
28 | get
29 | {
30 | Vector2 vector = this.endPoint - this.startPoint;
31 | return vector.normalized;
32 | }
33 | }
34 |
35 | public double length
36 | {
37 | get
38 | {
39 | Vector2 vector = this.endPoint - this.startPoint;
40 | return vector.length;
41 | }
42 | }
43 |
44 | public override string ToString()
45 | {
46 | return string.Format(
47 | "Line2(({0}, {1}), ({2}, {3})",
48 | this.startPoint.x,
49 | this.startPoint.y,
50 | this.endPoint.x,
51 | this.endPoint.y);
52 | }
53 |
54 | ///
55 | /// 求线段的交点
56 | ///
57 | /// 线段1
58 | /// 线段2
59 | /// 交点
60 | ///
61 | /// true --- 相交
62 | /// false --- 不相交
63 | ///
64 | public static bool Intersect(Line2 line1st, Line2 line2nd, ref Vector2 intersection,
65 | double tolerance = 1e-10)
66 | {
67 | Vector2 p = line1st.startPoint;
68 | Vector2 r = line1st.endPoint - line1st.startPoint;
69 | Vector2 q = line2nd.startPoint;
70 | Vector2 s = line2nd.endPoint - line2nd.startPoint;
71 | double rxs = Vector2.Cross(r, s);
72 | if (!Utils.IsEqualZero(rxs, tolerance))
73 | {
74 | double t = Vector2.Cross(q - p, s) / rxs;
75 | double u = Vector2.Cross(q - p, r) / rxs;
76 | if (t >= (0.0-tolerance) && t <= (1.0+tolerance)
77 | && u >= (0.0-tolerance) && u <= (1.0+tolerance))
78 | {
79 | intersection = p + t * r;
80 | return true;
81 | }
82 | }
83 | return false;
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/LitMath/Matrix3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LitMath
4 | {
5 | public struct Matrix3
6 | {
7 | public double m11;
8 | public double m12;
9 | public double m13;
10 | public double m21;
11 | public double m22;
12 | public double m23;
13 | public double m31;
14 | public double m32;
15 | public double m33;
16 |
17 | public Matrix3(
18 | double m11 = 0.0, double m12 = 0.0, double m13 = 0.0,
19 | double m21 = 0.0, double m22 = 0.0, double m23 = 0.0,
20 | double m31 = 0.0, double m32 = 0.0, double m33 = 0.0)
21 | {
22 | this.m11 = m11;
23 | this.m12 = m12;
24 | this.m13 = m13;
25 | this.m21 = m21;
26 | this.m22 = m22;
27 | this.m23 = m23;
28 | this.m31 = m31;
29 | this.m32 = m32;
30 | this.m33 = m33;
31 | }
32 |
33 | public void Set(
34 | double m11 = 0.0, double m12 = 0.0, double m13 = 0.0,
35 | double m21 = 0.0, double m22 = 0.0, double m23 = 0.0,
36 | double m31 = 0.0, double m32 = 0.0, double m33 = 0.0)
37 | {
38 | this.m11 = m11;
39 | this.m12 = m12;
40 | this.m13 = m13;
41 | this.m21 = m21;
42 | this.m22 = m22;
43 | this.m23 = m23;
44 | this.m31 = m31;
45 | this.m32 = m32;
46 | this.m33 = m33;
47 | }
48 |
49 | public override string ToString()
50 | {
51 | string pattern = @"Matrix3(
52 | {0,10:0.00}, {1,10:0.00}, {2,10:0.00},
53 | {3,10:0.00}, {4,10:0.00}, {5,10:0.00},
54 | {6,10:0.00}, {7,10:0.00}, {8,10:0.00} )";
55 | return string.Format(pattern,
56 | m11, m12, m13,
57 | m21, m22, m23,
58 | m31, m32, m33);
59 | }
60 |
61 | public double determinant
62 | {
63 | get
64 | {
65 | return m11 * m22 * m33 +
66 | m12 * m23 * m31 +
67 | m13 * m21 * m32 -
68 | m11 * m23 * m32 -
69 | m12 * m21 * m33 -
70 | m13 * m22 * m31;
71 | }
72 | }
73 |
74 | public Matrix3 inverse
75 | {
76 | get
77 | {
78 | double d = this.determinant;
79 | if (d == 0.0)
80 | return Matrix3.identity;
81 |
82 | Matrix3 tmp = new Matrix3();
83 | tmp.m11 = (m22 * m33 - m23 * m32) / d;
84 | tmp.m12 = (m13 * m32 - m12 * m33) / d;
85 | tmp.m13 = (m12 * m23 - m13 * m22) / d;
86 | tmp.m21 = (m23 * m31 - m21 * m33) / d;
87 | tmp.m22 = (m11 * m33 - m13 * m31) / d;
88 | tmp.m23 = (m13 * m21 - m11 * m23) / d;
89 | tmp.m31 = (m21 * m32 - m22 * m31) / d;
90 | tmp.m32 = (m12 * m31 - m11 * m32) / d;
91 | tmp.m33 = (m11 * m22 - m12 * m21) / d;
92 | return tmp;
93 | }
94 | }
95 |
96 | public Matrix3 transpose
97 | {
98 | get
99 | {
100 | return new Matrix3(
101 | m11, m21, m31,
102 | m12, m22, m32,
103 | m13, m23, m33);
104 | }
105 | }
106 |
107 | public Vector2 MultiplyPoint(Vector2 v)
108 | {
109 | return new Vector2(
110 | m11 * v.x + m12 * v.y + m13,
111 | m21 * v.x + m22 * v.y + m23);
112 | }
113 |
114 | public Vector2 MultiplyVector(Vector2 v)
115 | {
116 | return new Vector2(
117 | m11 * v.x + m12 * v.y,
118 | m21 * v.x + m22 * v.y);
119 | }
120 |
121 | public static Matrix3 identity
122 | {
123 | get
124 | {
125 | return new Matrix3(
126 | 1.0, 0.0, 0.0,
127 | 0.0, 1.0, 0.0,
128 | 0.0, 0.0, 1.0);
129 | }
130 | }
131 |
132 | public static Matrix3 zero
133 | {
134 | get
135 | {
136 | return new Matrix3(
137 | 0.0, 0.0, 0.0,
138 | 0.0, 0.0, 0.0,
139 | 0.0, 0.0, 0.0);
140 | }
141 | }
142 |
143 | public static Matrix3 Translate(Vector2 v)
144 | {
145 | return new Matrix3(
146 | 1.0, 0.0, v.x,
147 | 0.0, 1.0, v.y,
148 | 0.0, 0.0, 1.0);
149 | }
150 |
151 | public static Matrix3 Rotate(double angle)
152 | {
153 | return RotateInRadian(Utils.DegreeToRadian(angle));
154 | }
155 |
156 | public static Matrix3 RotateInRadian(double angle)
157 | {
158 | double cos = Math.Cos(angle);
159 | double sin = Math.Sin(angle);
160 | return new Matrix3(
161 | cos, -sin, 0.0,
162 | sin, cos, 0.0,
163 | 0.0, 0.0, 1.0);
164 | }
165 |
166 | public static Matrix3 Scale(Vector2 v)
167 | {
168 | return new Matrix3(
169 | v.x, 0.0, 0.0,
170 | 0.0, v.y, 0.0,
171 | 0.0, 0.0, 1.0);
172 | }
173 |
174 | public static Matrix3 operator *(Matrix3 a, Matrix3 b)
175 | {
176 | Matrix3 M = new Matrix3();
177 | M.m11 = a.m11 * b.m11 + a.m12 * b.m21 + a.m13 * b.m31;
178 | M.m12 = a.m11 * b.m12 + a.m12 * b.m22 + a.m13 * b.m32;
179 | M.m13 = a.m11 * b.m13 + a.m12 * b.m23 + a.m13 * b.m33;
180 | M.m21 = a.m21 * b.m11 + a.m22 * b.m21 + a.m23 * b.m31;
181 | M.m22 = a.m21 * b.m12 + a.m22 * b.m22 + a.m23 * b.m32;
182 | M.m23 = a.m21 * b.m13 + a.m22 * b.m23 + a.m23 * b.m33;
183 | M.m31 = a.m31 * b.m11 + a.m32 * b.m21 + a.m33 * b.m31;
184 | M.m32 = a.m31 * b.m12 + a.m32 * b.m22 + a.m33 * b.m32;
185 | M.m33 = a.m31 * b.m13 + a.m32 * b.m23 + a.m33 * b.m33;
186 | return M;
187 | }
188 |
189 | public static Vector2 operator *(Matrix3 m, Vector2 v)
190 | {
191 | return new Vector2(
192 | m.m11 * v.x + m.m12 * v.y + m.m13,
193 | m.m21 * v.x + m.m22 * v.y + m.m23);
194 | }
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/src/LitMath/Matrix4.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LitMath
4 | {
5 | public struct Matrix4
6 | {
7 | public double m11;
8 | public double m12;
9 | public double m13;
10 | public double m14;
11 | public double m21;
12 | public double m22;
13 | public double m23;
14 | public double m24;
15 | public double m31;
16 | public double m32;
17 | public double m33;
18 | public double m34;
19 | public double m41;
20 | public double m42;
21 | public double m43;
22 | public double m44;
23 |
24 | public Matrix4(
25 | double m11 = 0.0, double m12 = 0.0, double m13 = 0.0, double m14 = 0.0,
26 | double m21 = 0.0, double m22 = 0.0, double m23 = 0.0, double m24 = 0.0,
27 | double m31 = 0.0, double m32 = 0.0, double m33 = 0.0, double m34 = 0.0,
28 | double m41 = 0.0, double m42 = 0.0, double m43 = 0.0, double m44 = 0.0)
29 | {
30 | this.m11 = m11;
31 | this.m12 = m12;
32 | this.m13 = m13;
33 | this.m14 = m14;
34 |
35 | this.m21 = m21;
36 | this.m22 = m22;
37 | this.m23 = m23;
38 | this.m24 = m24;
39 |
40 | this.m31 = m31;
41 | this.m32 = m32;
42 | this.m33 = m33;
43 | this.m34 = m34;
44 |
45 | this.m41 = m41;
46 | this.m42 = m42;
47 | this.m43 = m43;
48 | this.m44 = m44;
49 | }
50 |
51 | public void Set(
52 | double m11 = 0.0, double m12 = 0.0, double m13 = 0.0, double m14 = 0.0,
53 | double m21 = 0.0, double m22 = 0.0, double m23 = 0.0, double m24 = 0.0,
54 | double m31 = 0.0, double m32 = 0.0, double m33 = 0.0, double m34 = 0.0,
55 | double m41 = 0.0, double m42 = 0.0, double m43 = 0.0, double m44 = 0.0)
56 | {
57 | this.m11 = m11;
58 | this.m12 = m12;
59 | this.m13 = m13;
60 | this.m14 = m14;
61 |
62 | this.m21 = m21;
63 | this.m22 = m22;
64 | this.m23 = m23;
65 | this.m24 = m24;
66 |
67 | this.m31 = m31;
68 | this.m32 = m32;
69 | this.m33 = m33;
70 | this.m34 = m34;
71 |
72 | this.m41 = m41;
73 | this.m42 = m42;
74 | this.m43 = m43;
75 | this.m44 = m44;
76 | }
77 |
78 | public override string ToString()
79 | {
80 | return string.Format(@"Matrix4(
81 | {0,10:0.00}, {1,10:0.00}, {2,10:0.00}, {3,10:0.00},
82 | {4,10:0.00}, {5,10:0.00}, {6,10:0.00}, {7,10:0.00},
83 | {8,10:0.00}, {9,10:0.00}, {10,10:0.00}, {11,10:0.00},
84 | {12,10:0.00}, {13,10:0.00}, {14,10:0.00}, {15,10:0.00} )",
85 | m11, m12, m13, m14,
86 | m21, m22, m23, m24,
87 | m31, m32, m33, m34,
88 | m41, m42, m43, m44);
89 | }
90 |
91 | public double determinant
92 | {
93 | get
94 | {
95 | double A0 = m11 * m22 - m12 * m21;
96 | double A1 = m11 * m23 - m13 * m21;
97 | double A2 = m11 * m24 - m14 * m21;
98 | double A3 = m12 * m23 - m13 * m22;
99 | double A4 = m12 * m24 - m14 * m22;
100 | double A5 = m13 * m24 - m14 * m23;
101 | double B0 = m31 * m42 - m32 * m41;
102 | double B1 = m31 * m43 - m33 * m41;
103 | double B2 = m31 * m44 - m34 * m41;
104 | double B3 = m32 * m43 - m33 * m42;
105 | double B4 = m32 * m44 - m34 * m42;
106 | double B5 = m33 * m44 - m34 * m43;
107 |
108 | return A0*B5 - A1*B4 + A2*B3 + A3*B2 - A4*B1 + A5*B0;
109 | }
110 | }
111 |
112 | public Matrix4 inverse
113 | {
114 | get
115 | {
116 | double d = this.determinant;
117 | if (d == 0.0)
118 | return Matrix4.identity;
119 |
120 | Matrix4 M = new Matrix4();
121 | M.m11 = (m23*m34*m42 - m24*m33*m42 + m24*m32*m43 -
122 | m22*m34*m43 - m23*m32*m44 + m22*m33*m44) / d;
123 | M.m12 = (m14*m33*m42 - m13*m34*m42 - m14*m32*m43 +
124 | m12*m34*m43 + m13*m32*m44 - m12*m33*m44) / d;
125 | M.m13 = (m13*m24*m42 - m14*m23*m42 + m14*m22*m43 -
126 | m12*m24*m43 - m13*m22*m44 + m12*m23*m44) / d;
127 | M.m14 = (m14*m23*m32 - m13*m24*m32 - m14*m22*m33 +
128 | m12*m24*m33 + m13*m22*m34 - m12*m23*m34) / d;
129 | M.m21 = (m24*m33*m41 - m23*m34*m41 - m24*m31*m43 +
130 | m21*m34*m43 + m23*m31*m44 - m21*m33*m44) / d;
131 | M.m22 = (m13*m34*m41 - m14*m33*m41 + m14*m31*m43 -
132 | m11*m34*m43 - m13*m31*m44 + m11*m33*m44) / d;
133 | M.m23 = (m14*m23*m41 - m13*m24*m41 - m14*m21*m43 +
134 | m11*m24*m43 + m13*m21*m44 - m11*m23*m44) / d;
135 | M.m24 = (m13*m24*m31 - m14*m23*m31 + m14*m21*m33 -
136 | m11*m24*m33 - m13*m21*m34 + m11*m23*m34) / d;
137 | M.m31 = (m22*m34*m41 - m24*m32*m41 + m24*m31*m42 -
138 | m21*m34*m42 - m22*m31*m44 + m21*m32*m44) / d;
139 | M.m32 = (m14*m32*m41 - m12*m34*m41 - m14*m31*m42 +
140 | m11*m34*m42 + m12*m31*m44 - m11*m32*m44) / d;
141 | M.m33 = (m12*m24*m41 - m14*m22*m41 + m14*m21*m42 -
142 | m11*m24*m42 - m12*m21*m44 + m11*m22*m44) / d;
143 | M.m34 = (m14*m22*m31 - m12*m24*m31 - m14*m21*m32 +
144 | m11*m24*m32 + m12*m21*m34 - m11*m22*m34) / d;
145 | M.m41 = (m23*m32*m41 - m22*m33*m41 - m23*m31*m42 +
146 | m21*m33*m42 + m22*m31*m43 - m21*m32*m43) / d;
147 | M.m42 = (m12*m33*m41 - m13*m32*m41 + m13*m31*m42 -
148 | m11*m33*m42 - m12*m31*m43 + m11*m32*m43) / d;
149 | M.m43 = (m13*m22*m41 - m12*m23*m41 - m13*m21*m42 +
150 | m11*m23*m42 + m12*m21*m43 - m11*m22*m43) / d;
151 | M.m44 = (m12*m23*m31 - m13*m22*m31 + m13*m21*m32 -
152 | m11*m23*m32 - m12*m21*m33 + m11*m22*m33) / d;
153 | return M;
154 | }
155 | }
156 |
157 | public Matrix4 transpose
158 | {
159 | get
160 | {
161 | return new Matrix4(
162 | m11, m21, m31, m41,
163 | m12, m22, m32, m42,
164 | m13, m23, m33, m43,
165 | m14, m24, m34, m44);
166 | }
167 | }
168 |
169 | public Vector3 MultiplyPoint(Vector3 v)
170 | {
171 | return new Vector3(
172 | m11 * v.x + m12 * v.y + m13 * v.z + m14,
173 | m21 * v.x + m22 * v.y + m23 * v.z + m24,
174 | m31 * v.x + m32 * v.y + m33 * v.z + m34);
175 | }
176 |
177 | public Vector3 MultiplyVector(Vector3 v)
178 | {
179 | return new Vector3(
180 | m11 * v.x + m12 * v.y + m13 * v.z,
181 | m21 * v.x + m22 * v.y + m23 * v.z,
182 | m31 * v.x + m32 * v.y + m33 * v.z);
183 | }
184 |
185 | public static Matrix4 identity
186 | {
187 | get
188 | {
189 | return new Matrix4(
190 | 1.0, 0.0, 0.0, 0.0,
191 | 0.0, 1.0, 0.0, 0.0,
192 | 0.0, 0.0, 1.0, 0.0,
193 | 0.0, 0.0, 0.0, 1.0);
194 | }
195 | }
196 |
197 | public static Matrix4 zero
198 | {
199 | get
200 | {
201 | return new Matrix4(
202 | 0.0, 0.0, 0.0, 0.0,
203 | 0.0, 0.0, 0.0, 0.0,
204 | 0.0, 0.0, 0.0, 0.0,
205 | 0.0, 0.0, 0.0, 0.0);
206 | }
207 | }
208 |
209 | public static Matrix4 Translate(Vector3 v)
210 | {
211 | return new Matrix4(
212 | 1.0, 0.0, 0.0, v.x,
213 | 0.0, 1.0, 0.0, v.y,
214 | 0.0, 0.0, 1.0, v.z,
215 | 0.0, 0.0, 0.0, 1.0);
216 | }
217 |
218 | public static Matrix4 RotateX(double angle)
219 | {
220 | return RotateXInRadian(Utils.DegreeToRadian(angle));
221 | }
222 |
223 | public static Matrix4 RotateXInRadian(double angle)
224 | {
225 | double cos = Math.Cos(angle);
226 | double sin = Math.Sin(angle);
227 | return new Matrix4(
228 | 1.0, 0.0, 0.0, 0.0,
229 | 0.0, cos, -sin, 0.0,
230 | 0.0, sin, cos, 0.0,
231 | 0.0, 0.0, 0.0, 1.0);
232 | }
233 |
234 | public static Matrix4 RotateY(double angle)
235 | {
236 | return RotateYInRadian(Utils.DegreeToRadian(angle));
237 | }
238 |
239 | public static Matrix4 RotateYInRadian(double angle)
240 | {
241 | double cos = Math.Cos(angle);
242 | double sin = Math.Sin(angle);
243 | return new Matrix4(
244 | cos, 0.0, sin, 0.0,
245 | 0.0, 1.0, 0.0, 0.0,
246 | -sin, 0.0, cos, 0.0,
247 | 0.0, 0.0, 0.0, 1.0);
248 | }
249 |
250 | public static Matrix4 RotateZ(double angle)
251 | {
252 | return RotateZInRadian(Utils.DegreeToRadian(angle));
253 | }
254 |
255 | public static Matrix4 RotateZInRadian(double angle)
256 | {
257 | double cos = Math.Cos(angle);
258 | double sin = Math.Sin(angle);
259 | return new Matrix4(
260 | cos, -sin, 0.0, 0.0,
261 | sin, cos, 0.0, 0.0,
262 | 0.0, 0.0, 1.0, 0.0,
263 | 0.0, 0.0, 0.0, 1.0);
264 | }
265 |
266 | public static Matrix4 Scale(Vector3 v)
267 | {
268 | return new Matrix4(
269 | v.x, 0.0, 0.0, 0.0,
270 | 0.0, v.y, 0.0, 0.0,
271 | 0.0, 0.0, v.z, 0.0,
272 | 0.0, 0.0, 0.0, 1.0);
273 | }
274 |
275 | public static Matrix4 AngleAxis(double angle, Vector3 axis)
276 | {
277 | return AngleAxisInRadian(Utils.DegreeToRadian(angle), axis);
278 | }
279 |
280 | public static Matrix4 AngleAxisInRadian(double angle, Vector3 axis)
281 | {
282 | Vector3 n = axis.normalized;
283 | double x = n.x;
284 | double y = n.y;
285 | double z = n.z;
286 | double sin = Math.Sin(angle);
287 | double cos = Math.Cos(angle);
288 | double l_cos = 1.0 - cos;
289 |
290 | Matrix4 M = new Matrix4();
291 | M.m11 = x * x * l_cos + cos;
292 | M.m12 = x * y * l_cos - z * sin;
293 | M.m13 = x * z * l_cos + y * sin;
294 | M.m21 = y * x * l_cos + z * sin;
295 | M.m22 = y * y * l_cos + cos;
296 | M.m23 = y * z * l_cos - x * sin;
297 | M.m31 = x * z * l_cos - y * sin;
298 | M.m32 = y * z * l_cos + x * sin;
299 | M.m33 = z * z * l_cos + cos;
300 | return M;
301 | }
302 |
303 | public static Matrix4 operator *(Matrix4 a, Matrix4 b)
304 | {
305 | Matrix4 M = new Matrix4();
306 |
307 | M.m11 = a.m11 * b.m11 + a.m12 * b.m21 + a.m13 * b.m31 + a.m14 * b.m41;
308 | M.m12 = a.m11 * b.m12 + a.m12 * b.m22 + a.m13 * b.m32 + a.m14 * b.m42;
309 | M.m13 = a.m11 * b.m13 + a.m12 * b.m23 + a.m13 * b.m33 + a.m14 * b.m43;
310 | M.m14 = a.m11 * b.m14 + a.m12 * b.m24 + a.m13 * b.m34 + a.m14 * b.m44;
311 |
312 | M.m21 = a.m21 * b.m11 + a.m22 * b.m21 + a.m23 * b.m31 + a.m24 * b.m41;
313 | M.m22 = a.m21 * b.m12 + a.m22 * b.m22 + a.m23 * b.m32 + a.m24 * b.m42;
314 | M.m23 = a.m21 * b.m13 + a.m22 * b.m23 + a.m23 * b.m33 + a.m24 * b.m43;
315 | M.m24 = a.m21 * b.m14 + a.m22 * b.m24 + a.m23 * b.m34 + a.m24 * b.m44;
316 |
317 | M.m31 = a.m31 * b.m11 + a.m32 * b.m21 + a.m33 * b.m31 + a.m34 * b.m41;
318 | M.m32 = a.m31 * b.m12 + a.m32 * b.m22 + a.m33 * b.m32 + a.m34 * b.m42;
319 | M.m33 = a.m31 * b.m13 + a.m32 * b.m23 + a.m33 * b.m33 + a.m34 * b.m43;
320 | M.m34 = a.m31 * b.m14 + a.m32 * b.m24 + a.m33 * b.m34 + a.m34 * b.m44;
321 |
322 | M.m41 = a.m41 * b.m11 + a.m42 * b.m21 + a.m43 * b.m31 + a.m44 * b.m41;
323 | M.m42 = a.m41 * b.m12 + a.m42 * b.m22 + a.m43 * b.m32 + a.m44 * b.m42;
324 | M.m43 = a.m41 * b.m13 + a.m42 * b.m23 + a.m43 * b.m33 + a.m44 * b.m43;
325 | M.m44 = a.m41 * b.m14 + a.m42 * b.m24 + a.m43 * b.m34 + a.m44 * b.m44;
326 |
327 | return M;
328 | }
329 |
330 | public static Vector3 operator *(Matrix4 m, Vector3 v)
331 | {
332 | return new Vector3(
333 | m.m11 * v.x + m.m12 * v.y + m.m13 * v.z + m.m14,
334 | m.m21 * v.x + m.m22 * v.y + m.m23 * v.z + m.m24,
335 | m.m31 * v.x + m.m32 * v.y + m.m33 * v.z + m.m34);
336 | }
337 | }
338 | }
339 |
--------------------------------------------------------------------------------
/src/LitMath/Quaternion.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LitMath
4 | {
5 | public struct Quaternion
6 | {
7 | public double x;
8 | public double y;
9 | public double z;
10 | public double w;
11 |
12 | public Quaternion(double x = 0.0, double y = 0.0, double z = 0.0, double w = 1.0)
13 | {
14 | this.x = x;
15 | this.y = y;
16 | this.z = z;
17 | this.w = w;
18 | }
19 |
20 | public void Set(double x, double y, double z, double w)
21 | {
22 | this.x = x;
23 | this.y = y;
24 | this.z = z;
25 | this.w = w;
26 | }
27 |
28 | public void SetIdentity()
29 | {
30 | Set(0.0, 0.0, 0.0, 1.0);
31 | }
32 |
33 | public override string ToString()
34 | {
35 | return string.Format("Quaternion({0}, {1}, {2}, {3})",
36 | x, y, z, w);
37 | }
38 |
39 | public double length
40 | {
41 | get
42 | {
43 | return Math.Sqrt(x*x + y*y + z*z + w*w);
44 | }
45 | }
46 |
47 | public void Normalize()
48 | {
49 | double len = this.length;
50 | if (len != 0.0)
51 | {
52 | this.x /= len;
53 | this.y /= len;
54 | this.z /= len;
55 | this.w /= len;
56 | }
57 | }
58 |
59 | public Quaternion normalized
60 | {
61 | get
62 | {
63 | double len = this.length;
64 | if (len != 0.0)
65 | {
66 | return new Quaternion(this.x / len, this.y / len, this.z / len, this.w / len);
67 | }
68 | return new Quaternion(this.x, this.y, this.z, this.w);
69 | }
70 | }
71 |
72 | public void Invert()
73 | {
74 | x = -x;
75 | y = -y;
76 | z = -z;
77 | }
78 |
79 | public Quaternion inverse
80 | {
81 | get
82 | {
83 | return new Quaternion(-x, -y, -z, w);
84 | }
85 | }
86 |
87 | public Matrix4 ToMatrix4()
88 | {
89 | Matrix4 matrix = new Matrix4();
90 | matrix.m11 = 1.0-2.0*(y*y+z*z);
91 | matrix.m12 = 2.0*(x*y-z*w);
92 | matrix.m13 = 2.0*(x*z+y*w);
93 | matrix.m14 = 0.0;
94 |
95 | matrix.m21 = 2.0*(x*y+z*w);
96 | matrix.m22 = 1.0-2.0*(x*x+z*z);
97 | matrix.m23 = 2.0*(y*z-x*w);
98 | matrix.m24 = 0.0;
99 |
100 | matrix.m31 = 2.0*(x*z-y*w);
101 | matrix.m32 = 2.0*(y*z+x*w);
102 | matrix.m33 = 1.0-2.0*(x*x+y*y);
103 | matrix.m34 = 0.0;
104 |
105 | matrix.m41 = 0.0;
106 | matrix.m42 = 0.0;
107 | matrix.m43 = 0.0;
108 | matrix.m44 = 1.0;
109 |
110 | return matrix;
111 | }
112 |
113 | public static Quaternion identity
114 | {
115 | get
116 | {
117 | return new Quaternion(0.0, 0.0, 0.0, 1.0);
118 | }
119 | }
120 |
121 | public static Quaternion AngleAxis(double angle, Vector3 axis)
122 | {
123 | return AngleAxisInRadian(Utils.DegreeToRadian(angle), axis);
124 | }
125 |
126 | public static Quaternion AngleAxisInRadian(double angle, Vector3 axis)
127 | {
128 | axis = axis.normalized;
129 | double scale = Math.Sin(angle / 2);
130 |
131 | Quaternion quat = new Quaternion();
132 | quat.w = Math.Cos(angle / 2);
133 | quat.x = axis.x * scale;
134 | quat.y = axis.y * scale;
135 | quat.z = axis.z * scale;
136 |
137 | return quat;
138 | }
139 |
140 | public static Quaternion FromToRotation(Vector3 from, Vector3 to)
141 | {
142 | Vector3 u = from.normalized;
143 | Vector3 v = to.normalized;
144 | double dot = Vector3.Dot(u, v);
145 | Vector3 w = Vector3.Cross(u, v);
146 |
147 | if (w.length == 0.0)
148 | {
149 | if (dot >= 0.0)
150 | {
151 | return Quaternion.identity;
152 | }
153 | else
154 | {
155 | Vector3 t = Vector3.Cross(u, new Vector3(1.0, 0.0, 0.0));
156 | if (Utils.IsEqualZero(t.length))
157 | {
158 | t = Vector3.Cross(u, new Vector3(0.0, 1.0, 0.0));
159 | }
160 | return new Quaternion(t.x, t.y, t.z, 0.0);
161 | }
162 | }
163 | else
164 | {
165 | double angleInRad = Math.Acos(dot);
166 | return Quaternion.AngleAxisInRadian(angleInRad, w);
167 | }
168 | }
169 |
170 | public static Quaternion operator *(Quaternion a, Quaternion b)
171 | {
172 | return new Quaternion(
173 | a.w * b.x + a.x * b.w + a.y * b.z - a.z * b.y,
174 | a.w * b.y - a.x * b.z + a.y * b.w + a.z * b.x,
175 | a.w * b.z + a.x * b.y - a.y * b.x + a.z * b.w,
176 | a.w * b.w - a.x * b.x - a.y * b.y - a.z * b.z);
177 | }
178 |
179 | public static Vector3 operator *(Quaternion q, Vector3 v)
180 | {
181 | double x = q.x;
182 | double y = q.y;
183 | double z = q.z;
184 | double w = q.w;
185 | double x2 = q.x * q.x;
186 | double y2 = q.y * q.y;
187 | double z2 = q.z * q.z;
188 | double w2 = q.w * q.w;
189 |
190 | return new Vector3(
191 | (x2 + w2 - y2 - z2) * v.x + 2.0 * (x * y - z * w) * v.y + 2.0 * (x * z + y * w) * v.z,
192 | 2.0 * (x * y + z * w) * v.x + (w2 - x2 + y2 - z2) * v.y + 2.0 * (y * z - x * w) * v.z,
193 | 2.0 * (x * z - y * w) * v.x + 2.0 * (x * w + y * z) * v.y + (w2 - x2 - y2 + z2) * v.z);
194 | }
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/src/LitMath/Rectangle2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LitMath
4 | {
5 | public struct Rectangle2
6 | {
7 | ///
8 | /// 位置,也就是矩形的左下角坐标
9 | ///
10 | public Vector2 location;
11 |
12 | ///
13 | /// 宽、高
14 | ///
15 | public double width;
16 | public double height;
17 |
18 | public Vector2 leftBottom
19 | {
20 | get { return location; }
21 | }
22 |
23 | public Vector2 leftTop
24 | {
25 | get
26 | {
27 | return new Vector2(this.location.x, this.location.y + height);
28 | }
29 | }
30 |
31 | public Vector2 rightTop
32 | {
33 | get
34 | {
35 | return new Vector2(this.location.x + this.width,
36 | this.location.y + this.height);
37 | }
38 | }
39 |
40 | public Vector2 rightBottom
41 | {
42 | get
43 | {
44 | return new Vector2(this.location.x + this.width, this.location.y);
45 | }
46 | }
47 |
48 | public Rectangle2(Vector2 location, double width, double height)
49 | {
50 | this.location = location;
51 | this.width = width;
52 | this.height = height;
53 | }
54 |
55 | public Rectangle2(Vector2 point1, Vector2 point2)
56 | {
57 | double minX = point1.x < point2.x ? point1.x : point2.x;
58 | double minY = point1.y < point2.y ? point1.y : point2.y;
59 | this.location = new Vector2(minX, minY);
60 | this.width = Math.Abs(point2.x - point1.x);
61 | this.height = Math.Abs(point2.y - point1.y);
62 | }
63 |
64 | public override string ToString()
65 | {
66 | return string.Format("Rectangle2(({0}, {1}), {2}, {3})",
67 | this.location.x,
68 | this.location.y,
69 | this.width,
70 | this.height);
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/LitMath/Utils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace LitMath
6 | {
7 | public class Utils
8 | {
9 | public const double EPSILON = 1E-05;
10 | public const double PI = 3.14159265358979323846;
11 |
12 | public static double Clamp(double value, double minv, double maxv)
13 | {
14 | return Math.Max(Math.Min(value, maxv), minv);
15 | }
16 |
17 | public static double DegreeToRadian(double angle)
18 | {
19 | return ((angle * PI) / 180.0);
20 | }
21 |
22 | public static bool IsEqual(double x, double y, double epsilon = EPSILON)
23 | {
24 | return IsEqualZero(x - y, epsilon);
25 | }
26 |
27 | public static bool IsEqualZero(double x, double epsilon = EPSILON)
28 | {
29 | return (Math.Abs(x) < epsilon);
30 | }
31 |
32 | public static double RadianToDegree(double angle)
33 | {
34 | return ((angle * 180.0) / PI);
35 | }
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/LitMath/Vector2.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LitMath
4 | {
5 | public struct Vector2
6 | {
7 | public double x;
8 | public double y;
9 |
10 | public Vector2(double x = 0.0, double y = 0.0)
11 | {
12 | this.x = x;
13 | this.y = y;
14 | }
15 |
16 | public void Set(double newX, double newY)
17 | {
18 | this.x = newX;
19 | this.y = newY;
20 | }
21 |
22 | public override string ToString()
23 | {
24 | return string.Format("Vector2({0}, {1})", this.x, this.y);
25 | }
26 |
27 | public override bool Equals(object obj)
28 | {
29 | if (!(obj is Vector2))
30 | return false;
31 |
32 | return Equals((Vector2)obj);
33 | }
34 |
35 | public bool Equals(Vector2 rhs)
36 | {
37 | return (Utils.IsEqual(x, rhs.x) && Utils.IsEqual(y, rhs.y));
38 | }
39 |
40 | public override int GetHashCode()
41 | {
42 | return x.GetHashCode() ^ y.GetHashCode();
43 | }
44 |
45 | public double length
46 | {
47 | get
48 | {
49 | return Math.Sqrt((this.x * this.x) + (this.y * this.y));
50 | }
51 | }
52 |
53 | public double lengthSqrd
54 | {
55 | get
56 | {
57 | return ((this.x * this.x) + (this.y * this.y));
58 | }
59 | }
60 |
61 | public void Normalize()
62 | {
63 | double length = this.length;
64 | if (length != 0.0)
65 | {
66 | this.x /= length;
67 | this.y /= length;
68 | }
69 | }
70 |
71 | public Vector2 normalized
72 | {
73 | get
74 | {
75 | double length = this.length;
76 | if (length != 0.0)
77 | {
78 | return new Vector2(this.x / length, this.y / length);
79 | }
80 | return this;
81 | }
82 | }
83 |
84 | public static double Dot(Vector2 a, Vector2 b)
85 | {
86 | return a.x * b.x + a.y * b.y;
87 | }
88 |
89 | public static double Cross(Vector2 a, Vector2 b)
90 | {
91 | return ((a.x * b.y) - (a.y * b.x));
92 | }
93 |
94 | ///
95 | /// Returns the unsigned angle in degrees between a and b.
96 | /// The smaller of the two possible angles between the two vectors is used.
97 | /// The result value range: [0, 180]
98 | ///
99 | public static double Angle(Vector2 a, Vector2 b)
100 | {
101 | return Utils.RadianToDegree(AngleInRadian(a, b));
102 | }
103 |
104 | ///
105 | /// Returns the unsigned angle in radians between a and b.
106 | /// The smaller of the two possible angles between the two vectors is used.
107 | /// The result value range: [0, PI]
108 | ///
109 | public static double AngleInRadian(Vector2 a, Vector2 b)
110 | {
111 | double num = a.length * b.length;
112 | if (num == 0.0)
113 | {
114 | return 0.0;
115 | }
116 | double num2 = Dot(a, b) / num;
117 | return Math.Acos(Utils.Clamp(num2, -1.0, 1.0));
118 | }
119 |
120 | ///
121 | /// Returns the signed acute clockwise angle in degrees between from and to.
122 | /// The result value range: [-180, 180]
123 | ///
124 | public static double SignedAngle(Vector2 from, Vector2 to)
125 | {
126 | return Utils.RadianToDegree(SignedAngleInRadian(from, to));
127 | }
128 |
129 | ///
130 | /// Returns the signed acute clockwise angle in radians between from and to.
131 | /// The result value range: [-PI, PI]
132 | ///
133 | public static double SignedAngleInRadian(Vector2 from, Vector2 to)
134 | {
135 | double rad = AngleInRadian(from, to);
136 | if (Cross(from, to) < 0)
137 | {
138 | rad = -rad;
139 | }
140 | return rad;
141 | }
142 |
143 | public static double Distance(Vector2 a, Vector2 b)
144 | {
145 | Vector2 vector = b - a;
146 | return vector.length;
147 | }
148 |
149 | public static Vector2 Rotate(Vector2 v, double angle)
150 | {
151 | return RotateInRadian(v, Utils.DegreeToRadian(angle));
152 | }
153 |
154 | public static Vector2 Rotate(Vector2 point, Vector2 basePoint, double angle)
155 | {
156 | return RotateInRadian(point, basePoint, Utils.DegreeToRadian(angle));
157 | }
158 |
159 | public static Vector2 RotateInRadian(Vector2 v, double rad)
160 | {
161 | double x = v.x * Math.Cos(rad) - v.y * Math.Sin(rad);
162 | double y = v.x * Math.Sin(rad) + v.y * Math.Cos(rad);
163 | return new Vector2(x, y);
164 | }
165 |
166 | public static Vector2 RotateInRadian(Vector2 point, Vector2 basePoint, double rad)
167 | {
168 | double cos = Math.Cos(rad);
169 | double sin = Math.Sin(rad);
170 | double x = point.x * cos - point.y * sin + basePoint.x * (1 - cos) + basePoint.y * sin;
171 | double y = point.x * sin + point.y * cos + basePoint.y * (1 - cos) + basePoint.x * sin;
172 |
173 | return new Vector2(x, y);
174 | }
175 |
176 | public static Vector2 operator +(Vector2 a, Vector2 b)
177 | {
178 | return new Vector2(a.x + b.x, a.y + b.y);
179 | }
180 |
181 | public static Vector2 operator -(Vector2 a, Vector2 b)
182 | {
183 | return new Vector2(a.x - b.x, a.y - b.y);
184 | }
185 |
186 | public static Vector2 operator -(Vector2 a)
187 | {
188 | return new Vector2(-a.x, -a.y);
189 | }
190 |
191 | public static Vector2 operator *(Vector2 a, double d)
192 | {
193 | return new Vector2(a.x * d, a.y * d);
194 | }
195 |
196 | public static Vector2 operator *(double d, Vector2 a)
197 | {
198 | return new Vector2(a.x * d, a.y * d);
199 | }
200 |
201 | public static Vector2 operator /(Vector2 a, double d)
202 | {
203 | return new Vector2(a.x / d, a.y / d);
204 | }
205 |
206 | public static bool operator ==(Vector2 lhs, Vector2 rhs)
207 | {
208 | return lhs.Equals(rhs);
209 | }
210 |
211 | public static bool operator !=(Vector2 lhs, Vector2 rhs)
212 | {
213 | return !(lhs == rhs);
214 | }
215 | }
216 | }
217 |
--------------------------------------------------------------------------------
/src/LitMath/Vector3.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace LitMath
4 | {
5 | public struct Vector3
6 | {
7 | public double x;
8 | public double y;
9 | public double z;
10 |
11 | public Vector3(double x = 0.0, double y = 0.0, double z = 0.0)
12 | {
13 | this.x = x;
14 | this.y = y;
15 | this.z = z;
16 | }
17 |
18 | public void Set(double newX, double newY, double newZ)
19 | {
20 | this.x = newX;
21 | this.y = newY;
22 | this.z = newZ;
23 | }
24 |
25 | public override string ToString()
26 | {
27 | return string.Format("Vector3({0}, {1}, {2})", this.x, this.y, this.z);
28 | }
29 |
30 | public override bool Equals(object obj)
31 | {
32 | if (!(obj is Vector3))
33 | return false;
34 |
35 | return Equals((Vector3)obj);
36 | }
37 |
38 | public bool Equals(Vector3 rhs)
39 | {
40 | return Utils.IsEqual(x, rhs.x)
41 | && Utils.IsEqual(y, rhs.y)
42 | && Utils.IsEqual(z, rhs.z);
43 | }
44 |
45 | public override int GetHashCode()
46 | {
47 | return x.GetHashCode() ^ y.GetHashCode() ^ z.GetHashCode();
48 | }
49 |
50 | public double length
51 | {
52 | get
53 | {
54 | return Math.Sqrt(((this.x * this.x) + (this.y * this.y)) + (this.z * this.z));
55 | }
56 | }
57 |
58 | public double lengthSqrd
59 | {
60 | get
61 | {
62 | return (((this.x * this.x) + (this.y * this.y)) + (this.z * this.z));
63 | }
64 | }
65 |
66 | public void Normalize()
67 | {
68 | double length = this.length;
69 | if (length != 0.0)
70 | {
71 | this.x /= length;
72 | this.y /= length;
73 | this.z /= length;
74 | }
75 | }
76 |
77 | public Vector3 normalized
78 | {
79 | get
80 | {
81 | double length = this.length;
82 | if (length != 0.0)
83 | {
84 | return new Vector3(this.x / length, this.y / length, this.z / length);
85 | }
86 | return this;
87 | }
88 | }
89 |
90 | public static double Dot(Vector3 a, Vector3 b)
91 | {
92 | return a.x * b.x + a.y * b.y + a.z * b.z;
93 | }
94 |
95 | public static Vector3 Cross(Vector3 a, Vector3 b)
96 | {
97 | return new Vector3(
98 | (a.y * b.z) - (a.z * b.y),
99 | (a.z * b.x) - (a.x * b.z),
100 | (a.x * b.y) - (a.y * b.x));
101 | }
102 |
103 | ///
104 | /// Returns the unsigned angle in degrees between a and b.
105 | /// The smaller of the two possible angles between the two vectors is used.
106 | /// The result value range: [0, 180]
107 | ///
108 | public static double Angle(Vector3 a, Vector3 b)
109 | {
110 | return Utils.RadianToDegree(AngleInRadian(a, b));
111 | }
112 |
113 | ///
114 | /// Returns the unsigned angle in radians between a and b.
115 | /// The smaller of the two possible angles between the two vectors is used.
116 | /// The result value range: [0, PI]
117 | ///
118 | public static double AngleInRadian(Vector3 a, Vector3 b)
119 | {
120 | double num = a.length * b.length;
121 | if (num == 0.0)
122 | {
123 | return 0.0;
124 | }
125 | double num2 = Dot(a, b) / num;
126 | return Math.Acos(Utils.Clamp(num2, -1.0, 1.0));
127 | }
128 |
129 | ///
130 | /// Returns the signed acute clockwise angle in degrees between from and to.
131 | /// The result value range: [-180, 180]
132 | /// The vector from which the angular difference is measured.
133 | /// The vector to which the angular difference is measured.
134 | /// A vector around which the other vectors are rotated.
135 | ///
136 | public static double SignedAngle(Vector3 from, Vector3 to, Vector3 axis)
137 | {
138 | return Utils.RadianToDegree(SignedAngleInRadian(from, to, axis));
139 | }
140 |
141 | ///
142 | /// Returns the signed acute clockwise angle in radians between from and to.
143 | /// The result value range: [-PI, PI]
144 | /// The vector from which the angular difference is measured.
145 | /// The vector to which the angular difference is measured.
146 | /// A vector around which the other vectors are rotated.
147 | ///
148 | public static double SignedAngleInRadian(Vector3 from, Vector3 to, Vector3 axis)
149 | {
150 | double rad = AngleInRadian(from, to);
151 | Vector3 n = Cross(from, to);
152 | if (Dot(n, axis) < 0)
153 | {
154 | rad = -rad;
155 | }
156 |
157 | return rad;
158 | }
159 |
160 | public static double Distance(Vector3 a, Vector3 b)
161 | {
162 | return (b - a).length;
163 | }
164 |
165 | public static Vector3 operator +(Vector3 a, Vector3 b)
166 | {
167 | return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
168 | }
169 |
170 | public static Vector3 operator -(Vector3 a, Vector3 b)
171 | {
172 | return new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
173 | }
174 |
175 | public static Vector3 operator -(Vector3 v)
176 | {
177 | return new Vector3(-v.x, -v.y, -v.z);
178 | }
179 |
180 | public static Vector3 operator *(Vector3 v, double d)
181 | {
182 | return new Vector3(v.x * d, v.y * d, v.z * d);
183 | }
184 |
185 | public static Vector3 operator *(double d, Vector3 v)
186 | {
187 | return new Vector3(v.x * d, v.y * d, v.z * d);
188 | }
189 |
190 | public static Vector3 operator /(Vector3 v, double d)
191 | {
192 | return new Vector3(v.x / d, v.y / d, v.z / d);
193 | }
194 |
195 | public static bool operator ==(Vector3 lhs, Vector3 rhs)
196 | {
197 | return lhs.Equals(rhs);
198 | }
199 |
200 | public static bool operator !=(Vector3 lhs, Vector3 rhs)
201 | {
202 | return !(lhs == rhs);
203 | }
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/src/LitMath/ViewUtils.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace LitMath
6 | {
7 | public class ViewUtils
8 | {
9 | public static Matrix4 ViewMatrix(Vector3 pos, Vector3 xAxis, Vector3 yAxis)
10 | {
11 | Vector3 xDir = xAxis.normalized;
12 | Vector3 yDir = yAxis.normalized;
13 | Vector3 zDir = Vector3.Cross(xDir, yDir).normalized;
14 |
15 | Matrix4 mRot = new Matrix4(
16 | xDir.x, xDir.y, xDir.z, 0,
17 | yDir.x, yDir.y, yDir.z, 0,
18 | zDir.x, zDir.y, zDir.z, 0,
19 | 0, 0, 0, 1);
20 |
21 | Matrix4 mPos = new Matrix4(
22 | 1, 0, 0, -pos.x,
23 | 0, 1, 0, -pos.y,
24 | 0, 0, 1, -pos.z,
25 | 0, 0, 0, 1);
26 |
27 | return mRot * mPos;
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的常规信息通过以下
6 | // 特性集控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("LitMath")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("LitMath")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 使此程序集中的类型
18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
19 | // 则将该类型上的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("ff1a9432-4167-4ab1-850a-14e12ff34559")]
24 |
25 | // 程序集的版本信息由下面四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 内部版本号
30 | // 修订号
31 | //
32 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("0.0.1.1")]
36 | [assembly: AssemblyFileVersion("0.0.1.1")]
37 |
--------------------------------------------------------------------------------
/test/Program.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Text;
4 |
5 | namespace Test
6 | {
7 | class Program
8 | {
9 | static void Main(string[] args)
10 | {
11 | //LitMath.Vector2 v = new LitMath.Vector2(0.7, 0.7);
12 | //v = LitMath.Vector2.RotateInRadian(v, LitMath.Utils.PI / 2);
13 | //Console.WriteLine(v.ToString());
14 | //Console.WriteLine(Math.Asin(0.5).ToString());
15 |
16 | {
17 | LitMath.Vector3 va = new LitMath.Vector3(0, 0, 1);
18 | LitMath.Vector3 vb = new LitMath.Vector3(0, 1, 0);
19 | LitMath.Vector3 axis = new LitMath.Vector3(1, 1, 0);
20 | double angle = LitMath.Vector3.SignedAngle(va, vb, axis);
21 | Console.WriteLine(angle);
22 | }
23 | {
24 | LitMath.Vector3 va = new LitMath.Vector3(0, 0, 1);
25 | LitMath.Vector3 vb = new LitMath.Vector3(0, 0, 1);
26 | LitMath.Vector3 axis = new LitMath.Vector3(1, 1, 0);
27 | double angle = LitMath.Vector3.SignedAngle(va, vb, axis);
28 | Console.WriteLine(angle);
29 | }
30 | {
31 | LitMath.Vector3 va = new LitMath.Vector3(0, 0, 1);
32 | LitMath.Vector3 vb = new LitMath.Vector3(0, 1, 0);
33 | LitMath.Vector3 axis = new LitMath.Vector3(0, 1, 1);
34 | double angle = LitMath.Vector3.SignedAngle(va, vb, axis);
35 | Console.WriteLine(angle);
36 | }
37 |
38 |
39 | return;
40 | //LitMath.Vector2 v1 = new LitMath.Vector2(1, 3);
41 | //Console.WriteLine(v1.ToString());
42 |
43 | LitMath.Line2 line1 = new LitMath.Line2(
44 | new LitMath.Vector2(0, 0),
45 | new LitMath.Vector2(10, 0));
46 | line1.startPoint.x = 10;
47 | LitMath.Line2 line2 = new LitMath.Line2(
48 | new LitMath.Vector2(5, 0),
49 | new LitMath.Vector2(5, 10));
50 |
51 | LitMath.Vector2 intersection = new LitMath.Vector2();
52 | if (LitMath.Line2.Intersect(line1, line2, ref intersection))
53 | {
54 | Console.WriteLine("相交: " + intersection.ToString());
55 | }
56 |
57 | LitMath.Rectangle2 rect = new LitMath.Rectangle2(new LitMath.Vector2(10, 10), 10, 20);
58 | Console.WriteLine(rect.ToString());
59 | Console.WriteLine(rect.leftBottom.ToString());
60 | Console.WriteLine(rect.leftTop.ToString());
61 | Console.WriteLine(rect.rightTop.ToString());
62 | Console.WriteLine(rect.rightBottom.ToString());
63 |
64 | LitMath.Circle2 circle = new LitMath.Circle2(new LitMath.Vector2(25, 25), 10);
65 | Console.WriteLine(circle.ToString());
66 | Console.WriteLine(circle.diameter.ToString());
67 | }
68 | }
69 |
70 | }
71 |
--------------------------------------------------------------------------------
/test/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.CompilerServices;
3 | using System.Runtime.InteropServices;
4 |
5 | // 有关程序集的常规信息通过以下
6 | // 特性集控制。更改这些特性值可修改
7 | // 与程序集关联的信息。
8 | [assembly: AssemblyTitle("Test")]
9 | [assembly: AssemblyDescription("")]
10 | [assembly: AssemblyConfiguration("")]
11 | [assembly: AssemblyCompany("")]
12 | [assembly: AssemblyProduct("Test")]
13 | [assembly: AssemblyCopyright("Copyright © 2017")]
14 | [assembly: AssemblyTrademark("")]
15 | [assembly: AssemblyCulture("")]
16 |
17 | // 将 ComVisible 设置为 false 使此程序集中的类型
18 | // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
19 | // 则将该类型上的 ComVisible 特性设置为 true。
20 | [assembly: ComVisible(false)]
21 |
22 | // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
23 | [assembly: Guid("779bbc10-9570-425a-8cd6-68fc70316fc4")]
24 |
25 | // 程序集的版本信息由下面四个值组成:
26 | //
27 | // 主版本
28 | // 次版本
29 | // 内部版本号
30 | // 修订号
31 | //
32 | // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
33 | // 方法是按如下所示使用“*”:
34 | // [assembly: AssemblyVersion("1.0.*")]
35 | [assembly: AssemblyVersion("1.0.0.0")]
36 | [assembly: AssemblyFileVersion("1.0.0.0")]
37 |
--------------------------------------------------------------------------------
/test/Test.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | x86
6 | 8.0.30703
7 | 2.0
8 | {35D3E59A-F22F-4F75-8F65-C296EAFC7703}
9 | Exe
10 | Properties
11 | Test
12 | Test
13 | v2.0
14 | 512
15 |
16 |
17 | x86
18 | true
19 | full
20 | false
21 | ..\bin\Debug\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | x86
28 | pdbonly
29 | true
30 | ..\bin\Release\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 | {5C1D6D42-A59E-4A42-84B0-F444E63736DF}
47 | LitMath
48 |
49 |
50 |
51 |
58 |
--------------------------------------------------------------------------------