Released alpha v2.3.1.52
This commit is contained in:
parent
d6234f0004
commit
07cb6a2369
14
.gitignore
vendored
14
.gitignore
vendored
@ -1,13 +1,11 @@
|
|||||||
# Visual Studio stuff
|
# Useless Visual Studio stuff
|
||||||
*.csproj
|
|
||||||
*.editorconfig
|
|
||||||
*.sln
|
|
||||||
/Nerd_STF/.vs/
|
/Nerd_STF/.vs/
|
||||||
|
|
||||||
|
# Build Stuff
|
||||||
/Nerd_STF/obj
|
/Nerd_STF/obj
|
||||||
/Nerd_STF/bin/Debug
|
/Nerd_STF/bin
|
||||||
/Nerd_STF/bin/Release/net6.0/Nerd_STF.deps.json
|
*.dll
|
||||||
/Nerd_STF/bin/Release/net6.0/Nerd_STF.dll
|
*.pdb
|
||||||
/Nerd_STF/bin/Release/net6.0/Nerd_STF.pdb
|
|
||||||
|
|
||||||
# Testing project
|
# Testing project
|
||||||
/Testing
|
/Testing
|
||||||
|
|||||||
216
Changelog.md
216
Changelog.md
@ -1,4 +1,4 @@
|
|||||||
# Nerd_STF v2.3.1.39
|
# Nerd_STF v2.3.1.52
|
||||||
|
|
||||||
***Read this to know what works and what doesn't!***
|
***Read this to know what works and what doesn't!***
|
||||||
|
|
||||||
@ -25,11 +25,23 @@ The following types have been checked for the most part and can be safe to use:
|
|||||||
- `Nerd_STF.Exceptions.InvalidSizeException`
|
- `Nerd_STF.Exceptions.InvalidSizeException`
|
||||||
- `Nerd_STF.Exceptions.Nerd_STFException`
|
- `Nerd_STF.Exceptions.Nerd_STFException`
|
||||||
- `Nerd_STF.Exceptions.NoInverseException`
|
- `Nerd_STF.Exceptions.NoInverseException`
|
||||||
|
- `Nerd_STF.Extensions.Container2DExtension`
|
||||||
|
- `Nerd_STF.Extensions.ConversionExtension`
|
||||||
|
- `Nerd_STF.Extensions.EquationExtension`
|
||||||
- `Nerd_STF.Extensions.ToFillExtension`
|
- `Nerd_STF.Extensions.ToFillExtension`
|
||||||
|
- `Nerd_STF.Graphics.CMYKA`
|
||||||
|
- `Nerd_STF.Graphics.CMYKAByte`
|
||||||
- `Nerd_STF.Graphics.ColorChannel`
|
- `Nerd_STF.Graphics.ColorChannel`
|
||||||
|
- `Nerd_STF.Graphics.HSVA`
|
||||||
|
- `Nerd_STF.Graphics.HSVAByte`
|
||||||
|
- `Nerd_STF.Graphics.IColor`
|
||||||
|
- `Nerd_STF.Graphics.IColorByte`
|
||||||
- `Nerd_STF.Graphics.IlluminationFlags`
|
- `Nerd_STF.Graphics.IlluminationFlags`
|
||||||
- `Nerd_STF.Graphics.IlluminationModel`
|
- `Nerd_STF.Graphics.IlluminationModel`
|
||||||
|
- `Nerd_STF.Graphics.Image`
|
||||||
- `Nerd_STF.Graphics.Material`
|
- `Nerd_STF.Graphics.Material`
|
||||||
|
- `Nerd_STF.Graphics.RGBA`
|
||||||
|
- `Nerd_STF.Graphics.RGBAByte`
|
||||||
- `Nerd_STF.Graphics.TextureConfig`
|
- `Nerd_STF.Graphics.TextureConfig`
|
||||||
- `Nerd_STF.Mathematics.Angle`
|
- `Nerd_STF.Mathematics.Angle`
|
||||||
- `Nerd_STF.Mathematics.Calculus`
|
- `Nerd_STF.Mathematics.Calculus`
|
||||||
@ -41,32 +53,13 @@ The following types have been checked for the most part and can be safe to use:
|
|||||||
- `Nerd_STF.Mathematics.Int3`
|
- `Nerd_STF.Mathematics.Int3`
|
||||||
- `Nerd_STF.Mathematics.Int4`
|
- `Nerd_STF.Mathematics.Int4`
|
||||||
- `Nerd_STF.Mathematics.Mathf`
|
- `Nerd_STF.Mathematics.Mathf`
|
||||||
|
- `Nerd_STF.Mathematics.Geometry.ISubdividable`
|
||||||
- `Nerd_STF.Mathematics.NumberSystems.Complex`
|
- `Nerd_STF.Mathematics.NumberSystems.Complex`
|
||||||
- `Nerd_STF.Mathematics.NumberSystems.Quaternion`
|
- `Nerd_STF.Mathematics.NumberSystems.Quaternion`
|
||||||
- With the exception of the following methods:
|
|
||||||
- `Quaternion.FromAngles(Angle, Angle, Angle?)`
|
|
||||||
- `Quaternion.FromAngles(Float3, Angle.Type)`
|
|
||||||
- `Quaternion.FromVector(Vector3d)`
|
|
||||||
- `GetAngle()`
|
|
||||||
- `GetAxis()`
|
|
||||||
- `ToAngles()`
|
|
||||||
- `ToVector()`
|
|
||||||
- `Nerd_STF.Mathematics.Samples.Constants`
|
- `Nerd_STF.Mathematics.Samples.Constants`
|
||||||
- `Nerd_STF.Mathematics.Samples.Equations`
|
- `Nerd_STF.Mathematics.Samples.Equations`
|
||||||
|
|
||||||
The following types haven't been checked yet, and should still be taken with a grain of salt:
|
The following types haven't been checked yet, and should still be taken with a grain of salt:
|
||||||
- `Nerd_STF.Extensions.Container2DExtension`
|
|
||||||
- `Nerd_STF.Extensions.ConversionExtension`
|
|
||||||
- `Nerd_STF.Extensions.EquationExtension`
|
|
||||||
- `Nerd_STF.Graphics.CMYKA`
|
|
||||||
- `Nerd_STF.Graphics.CMYKAByte`
|
|
||||||
- `Nerd_STF.Graphics.HSVA`
|
|
||||||
- `Nerd_STF.Graphics.HSVAByte`
|
|
||||||
- `Nerd_STF.Graphics.IColor`
|
|
||||||
- `Nerd_STF.Graphics.IColorByte`
|
|
||||||
- `Nerd_STF.Graphics.Image`
|
|
||||||
- `Nerd_STF.Graphics.RGBA`
|
|
||||||
- `Nerd_STF.Graphics.RGBAByte`
|
|
||||||
- `Nerd_STF.Mathematics.Algebra.IMatrix`
|
- `Nerd_STF.Mathematics.Algebra.IMatrix`
|
||||||
- `Nerd_STF.Mathematics.Algebra.Matrix`
|
- `Nerd_STF.Mathematics.Algebra.Matrix`
|
||||||
- `Nerd_STF.Mathematics.Algebra.Matrix2x2`
|
- `Nerd_STF.Mathematics.Algebra.Matrix2x2`
|
||||||
@ -76,7 +69,6 @@ The following types haven't been checked yet, and should still be taken with a g
|
|||||||
- `Nerd_STF.Mathematics.Algebra.Vector3d`
|
- `Nerd_STF.Mathematics.Algebra.Vector3d`
|
||||||
- `Nerd_STF.Mathematics.Geometry.Box2D`
|
- `Nerd_STF.Mathematics.Geometry.Box2D`
|
||||||
- `Nerd_STF.Mathematics.Geometry.Box3D`
|
- `Nerd_STF.Mathematics.Geometry.Box3D`
|
||||||
- `Nerd_STF.Mathematics.Geometry.ISubdividable`
|
|
||||||
- `Nerd_STF.Mathematics.Geometry.ITriangulatable`
|
- `Nerd_STF.Mathematics.Geometry.ITriangulatable`
|
||||||
- `Nerd_STF.Mathematics.Geometry.Line`
|
- `Nerd_STF.Mathematics.Geometry.Line`
|
||||||
- `Nerd_STF.Mathematics.Geometry.Polygon`
|
- `Nerd_STF.Mathematics.Geometry.Polygon`
|
||||||
@ -85,134 +77,74 @@ The following types haven't been checked yet, and should still be taken with a g
|
|||||||
- `Nerd_STF.Mathematics.Geometry.Triangle`
|
- `Nerd_STF.Mathematics.Geometry.Triangle`
|
||||||
- `Nerd_STF.Mathematics.Geometry.Vert`
|
- `Nerd_STF.Mathematics.Geometry.Vert`
|
||||||
|
|
||||||
I've checked a total of 39 types, with 29 left to go. It sounds like I'm over halfway, but really I've saved all of the annoying ones that are likely wrong to be checked next. My 39 done includes a bunch of really simple types that never needed checking in the first place too. But there are some done, like any type in the Mathematics directory.
|
16 left to go.
|
||||||
|
|
||||||
|
Honestly, most of the time taken for this update was spent on Quaternions. Turns out my multiply function was subtley wrong. Who knew!
|
||||||
|
Just a relief to be done with it. The other stuff wasn't too much of a problem. Matrixes are probably going to be a huge pain if they don't work first try, though. That'll be in the next update, probably.
|
||||||
|
|
||||||
|
I should also note that I just realized after way to long that the `.csproj` file isn't included in the Github. It's included in this new release, and sometime in the future I'll go back and add a correctly working `.csproj` file to all the other releases as well (with the exception of the legacy Nerd_STF 2021 versions likely. We'll see). I'll now not include the `/bin` build files. They'll be in the release and you can build it yourself if you need to now. Anyway, have fun.
|
||||||
|
|
||||||
```
|
```
|
||||||
* Nerd_STF
|
* Nerd_STF
|
||||||
* Exceptions
|
|
||||||
+ MathException
|
|
||||||
+ UndefinedException
|
|
||||||
* Extensions
|
* Extensions
|
||||||
+ EquationExtension
|
* Container2DExtension
|
||||||
|
= Fixed `Flatten<T>(T[,], Int2)`
|
||||||
|
= `GetColumn<T>(T[,], int, int)` and `GetRow<T>(T[,], int, int)` have been fixed (They had swapped roles)
|
||||||
|
* ConversionExtension
|
||||||
|
+ ToFill<T>(T[])
|
||||||
|
+ ToFill<T>(T[,], Int2)
|
||||||
|
+ ToFill2D<T>(T[,])
|
||||||
|
* EquationExtension
|
||||||
|
= Fixed `Scale(Equation, float, ScaleType)` by swapping all instances of `x` and `value` (oops)
|
||||||
|
= Moved `ScaleType` out of parent class `EquationExtension` and into namespace `Nerd_STF`
|
||||||
|
* Geometry
|
||||||
|
* ITriangulatable
|
||||||
|
+ TriangulateAll<T>(T[]) where T : ITriangulatable
|
||||||
|
* Graphics
|
||||||
|
+ Renamed `IColor` to `IColorFloat`
|
||||||
|
= Made IColor an object both `IColorFloat` and `IColorByte` inherit from.
|
||||||
|
* CMYKA
|
||||||
|
= Made `ToRGBA()` include the alpha value of the color.
|
||||||
|
* CMYKAByte
|
||||||
|
= In `ToHSVA()` and `ToHSVAByte()`, swapped some conversions from `RGBA` to `CMYKA`
|
||||||
|
* HSVA
|
||||||
|
= Made `ToRGBA()` include the alpha value of the color.
|
||||||
|
* Image
|
||||||
|
- Removed some useless constructors
|
||||||
|
= Fixed some broken constructors
|
||||||
* Mathematics
|
* Mathematics
|
||||||
* NumberSystems
|
|
||||||
* Complex
|
|
||||||
+ Inverse
|
|
||||||
+ GetAngle()
|
|
||||||
= Fixed `ToString()` and all overloads from adding a redundant negative sign sometimes in the imaginary component.
|
|
||||||
= Replaced the `/` operator with a multiplication by its inverse.
|
|
||||||
* Quaternion
|
|
||||||
+ Inverse
|
|
||||||
= Fixed `ToString()` and all overloads from adding a redundant negative sign sometimes in the i, j, and k components.
|
|
||||||
= Replaced the `/` operator with a multiplication by its inverse.
|
|
||||||
* Algebra
|
* Algebra
|
||||||
* Vector2d
|
* Vector2d
|
||||||
- static Product(params Vector2d[])
|
= Removed a default parameter value in `ToString(Angle.Type)` to prevent confusion.
|
||||||
- static Divide(Vector2d, params Vector2d[])
|
* Vector3d
|
||||||
- operator *(Vector2d, Angle)
|
+ string ToString()
|
||||||
- operator *(Vector2d, Vector2d)
|
+ string ToString(Angle.Type)
|
||||||
- operator /(Vector2d, Angle)
|
+ string ToString(IFormatProvider, Angle.Type)
|
||||||
- operator /(Vector2d, Vector2d)
|
= Fixed `ToXYZ()`
|
||||||
= Made `ToXYZ()` actually work
|
* NumberSystems
|
||||||
* Vector3d
|
* Complex
|
||||||
- static Product(params Vector3d[])
|
+ operator ~(Complex)
|
||||||
- static Divide(Vector3d, params Vector3d[])
|
* Quaternion
|
||||||
- operator *(Vector3d, Angle)
|
+ Rotate(Float3)
|
||||||
- operator *(Vector3d, Vector3d)
|
+ Rotate(Vector3d)
|
||||||
- operator /(Vector3d, Angle)
|
+ operator ~(Quaternion)
|
||||||
- operator /(Vector3d, Vector3d)
|
- ToVector()
|
||||||
* Calculus
|
= Gave `IJK` proper get and set accessors.
|
||||||
+ GetDynamicIntegral(Equation, Equation, Equation, float)
|
= Renamed some terms in `ToString()`
|
||||||
= Made `GetDerivative(Equation, float)` calculate specific values on the fly, and removed the min/max.
|
= Fixed the `Quaternion.FromAngles(*)` methods to do the proper thing.
|
||||||
* Graphics
|
= Fixed `Quaternion.Rotate(Quaternion)`
|
||||||
* HSVA
|
= Fixed `Quaternion.Rotate(Float3)`
|
||||||
- static LerpSquared(HSVA, HSVA, float, Angle.Type, bool = true)
|
= Fixed `operator *(Quaternion, Quaternion)`
|
||||||
- operator *(HSVA, HSVA)
|
= Optimized `GetAxis()`
|
||||||
- operator /(HSVA, HSVA)
|
= Simplified `ToXYZ()`
|
||||||
* HSVAByte
|
= Swapped the order of `Rotate(Quaternion)`
|
||||||
- static LerpSquared(HSVAByte, HSVAByte, float, Angle.Type, bool = true)
|
= Made `GetAxis()` not accidentally create an infinite vector.
|
||||||
* Angle
|
* Angle
|
||||||
+ Reflected
|
+ Complimentary
|
||||||
+ static Max(bool, params Angle[])
|
+ Supplementary
|
||||||
+ static Min(bool, params Angle[])
|
|
||||||
- operator *(Angle, Angle)
|
|
||||||
- operator /(Angle, Angle)
|
|
||||||
= Made `Angle(float, Type)` use a lambda expression
|
|
||||||
= Made `Bounded` use the `AbsoluteMod()` function instead of the default `%` expression
|
|
||||||
= Replaced an accidental `Mathf.Floor()` call with a `Mathf.Round()` call in `Floor()`
|
|
||||||
= Made `operator -(Angle)` actually give you the reverse angle (not the reflected angle)
|
|
||||||
* Float2
|
* Float2
|
||||||
= Made `Median(params Float2)` not use an unneccesary average
|
+ operator *(Float2, Quaternion)
|
||||||
= Made `ToVector()` not create an angle out of `ArcTan(float)`, as it already is one
|
|
||||||
= Optimized `Divide(Float2, params Float2[])` to divide a product instead of individually dividing
|
|
||||||
= Optimized `Subtract(Float2, params Float2[])` to subtract a sum instead of individually subtracting
|
|
||||||
* Float3
|
* Float3
|
||||||
= Made `Median(params Float3)` not use an unneccesary average
|
+ operator *(Float3, Quaternion)
|
||||||
= Made `ToVector()` not create an angle out of the arc trig functions, as they already are angles
|
= Fixed `ToVector()`
|
||||||
= Optimized `Divide(Float3, params Float3[])` to divide a product instead of individually dividing
|
|
||||||
= Optimized `Subtract(Float3, params Float3[])` to subtract a sum instead of individually subtracting
|
|
||||||
* Float4
|
|
||||||
= Marked `Far` and `Near` as obsolete/deprecated, as they have been replaced by `HighW` and `LowW`
|
|
||||||
= Made `Median(params Float4)` not use an unneccesary average
|
|
||||||
= Optimized `Divide(Float4, params Float4[])` to divide a product instead of individually dividing
|
|
||||||
= Optimized `Subtract(Float4, params Float4[])` to subtract a sum instead of individually subtracting
|
|
||||||
* Int2
|
|
||||||
= Made `Median(params Float4)` not use an unneccesary average
|
|
||||||
= Optimized `Divide(Float4, params Float4[])` to divide a product instead of individually dividing
|
|
||||||
= Optimized `Subtract(Float4, params Float4[])` to subtract a sum instead of individually subtracting
|
|
||||||
* Int3
|
|
||||||
= Made `Median(params Float4)` not use an unneccesary average
|
|
||||||
= Optimized `Divide(Float4, params Float4[])` to divide a product instead of individually dividing
|
|
||||||
= Optimized `Subtract(Float4, params Float4[])` to subtract a sum instead of individually subtracting
|
|
||||||
* Int4
|
|
||||||
+ LowW
|
|
||||||
= Marked `Far` as obsolete/deprecated, as it has been replaced by `HighW`
|
|
||||||
= Made `Median(params Float4)` not use an unneccesary average
|
|
||||||
= Optimized `Divide(Float4, params Float4[])` to divide a product instead of individually dividing
|
|
||||||
= Optimized `Subtract(Float4, params Float4[])` to subtract a sum instead of individually subtracting
|
|
||||||
* Mathf
|
|
||||||
+ AbsoluteMod(float)
|
|
||||||
+ Binomial(int, int, float)
|
|
||||||
+ Factors(int)
|
|
||||||
+ PowerMod(int, int, int)
|
|
||||||
= Fixed `Ceiling(float)` from rounding up when it shouldn't
|
|
||||||
= Made `Median(params float[])` actually calculate the right midpoint
|
|
||||||
= Removed two unneeded `Average(float, float)` calls in `Median(params float[])`
|
|
||||||
= Replaced the `Floor(float)` and `Ceiling(float)` calls in `Median(params float[])` with a better alternative
|
|
||||||
= Replaced the mod in `Sin(float)` with an `AbsoluteMod(float, float)` call
|
|
||||||
= Made `MadeEquation(Dictionary<float, float>)` actually work.
|
|
||||||
= Added caching to Power(float, int) for the absolute max
|
|
||||||
= Fixed an if statement and added another one to prevent extra computation in `Power(float, int)`
|
|
||||||
= Added caching to Power(int, int) for the absolute max
|
|
||||||
= Fixed an if statement and added another one to prevent extra computation in `Power(int, int)`
|
|
||||||
= Made the `Lerp(int, int, float, bool)` function not call itself infinitely many times.
|
|
||||||
= Replaced a multiplication with a division in `Root(float, float)`
|
|
||||||
= Made the `Average(int[])` function give you the int average instead of the float average (unlike `Average(float[])`)
|
|
||||||
= Replaced the float return statement with an Angle in `ArcCos(float)`
|
|
||||||
= Replaced the float return statement with an Angle in `ArcCot(float)`
|
|
||||||
= Replaced the float return statement with an Angle in `ArcCsc(float)`
|
|
||||||
= Replaced the float return statement with an Angle in `ArcSec(float)`
|
|
||||||
= Replaced the float return statement with an Angle in `ArcSin(float)`
|
|
||||||
= Replaced the float return statement with an Angle in `ArcTan(float)`
|
|
||||||
= Replaced the float return statement with an Angle in `ArcTan2(float, float)`
|
|
||||||
= Optimized `ArcCos(float)` to use presets
|
|
||||||
= Optimized `Divide(float, params float[])` to use other functions.
|
|
||||||
= Optimized `Divide(int, params int[])` to use other functions.
|
|
||||||
= Optimized `Subtract(float, params float[])` to subtract a sum instead of individually subtracting
|
|
||||||
= Optimized `Subtract(int, params int[])` to subtract a sum instead of individually subtracting
|
|
||||||
= Made `Clamp(int, int, int)` not remake code and use `Clamp(float, float, float)`
|
|
||||||
= Made `Lerp(int, int, float, bool)` cast to an int instead of flooring
|
|
||||||
= Made `Lerp(float, float, float, bool)` not break when clamping and A is greater than B
|
|
||||||
= Made `Median<T>(params T[])` not use an unneccesary average
|
|
||||||
= Made `Power(int, int)` not care about absolutes
|
|
||||||
= Made `Variance(params float[])` correctly calculate variance.
|
|
||||||
* Quaternion
|
|
||||||
= Made `GetAngle()` not create an angle out of `ArcCos(float)`, as it already is one
|
|
||||||
= Made `ToAngles()` not create angles out of arc trig functions, as they are already angles
|
|
||||||
* Samples
|
|
||||||
* Constants
|
|
||||||
= Swapped `DegToRad` and `RadToDeg`
|
|
||||||
* Equations
|
|
||||||
= Moved `static Scale(Equation, float, ScaleType)` to `EquationExtension`
|
|
||||||
= Moved `ScaleType` to `EquationExtension`
|
|
||||||
```
|
```
|
||||||
|
|||||||
4
Nerd_STF/.editorconfig
Normal file
4
Nerd_STF/.editorconfig
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
[*.cs]
|
||||||
|
|
||||||
|
# CA1050: Declare types in namespaces
|
||||||
|
dotnet_diagnostic.CA1050.severity = warning
|
||||||
@ -5,20 +5,20 @@ public static class Container2DExtension
|
|||||||
public static T[] Flatten<T>(this T[,] array, Int2 size)
|
public static T[] Flatten<T>(this T[,] array, Int2 size)
|
||||||
{
|
{
|
||||||
T[] res = new T[size.x * size.y];
|
T[] res = new T[size.x * size.y];
|
||||||
for (int x = 0; x < size.x; x++) for (int y = 0; y < size.y; y++) res[x + y * size.y] = array[x, y];
|
for (int x = 0; x < size.x; x++) for (int y = 0; y < size.y; y++) res[x + y * size.x] = array[y, x];
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static T[] GetColumn<T>(this T[,] array, int column, int length)
|
public static T[] GetColumn<T>(this T[,] array, int column, int length)
|
||||||
{
|
{
|
||||||
T[] res = new T[length];
|
T[] res = new T[length];
|
||||||
for (int i = 0; i < length; i++) res[i] = array[column, i];
|
for (int i = 0; i < length; i++) res[i] = array[i, column];
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
public static T[] GetRow<T>(this T[,] array, int row, int length)
|
public static T[] GetRow<T>(this T[,] array, int row, int length)
|
||||||
{
|
{
|
||||||
T[] res = new T[length];
|
T[] res = new T[length];
|
||||||
for (int i = 0; i < length; i++) res[i] = array[i, row];
|
for (int i = 0; i < length; i++) res[i] = array[row, i];
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -10,4 +10,8 @@ public static class ConversionExtension
|
|||||||
foreach (KeyValuePair<TKey, TValue> pair in pairs) res.Add(pair.Key, pair.Value);
|
foreach (KeyValuePair<TKey, TValue> pair in pairs) res.Add(pair.Key, pair.Value);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Fill<T> ToFill<T>(this T[] arr) => i => arr[i];
|
||||||
|
public static Fill<T> ToFill<T>(this T[,] arr, Int2 size) => arr.Flatten(size).ToFill();
|
||||||
|
public static Fill2D<T> ToFill2D<T>(this T[,] arr) => (x, y) => arr[x, y];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,16 +4,9 @@ public static class EquationExtension
|
|||||||
{
|
{
|
||||||
public static Equation Scale(this Equation equ, float value, ScaleType type = ScaleType.Both) => type switch
|
public static Equation Scale(this Equation equ, float value, ScaleType type = ScaleType.Both) => type switch
|
||||||
{
|
{
|
||||||
ScaleType.X => x => equ(value / x),
|
ScaleType.X => x => equ(x / value),
|
||||||
ScaleType.Y => x => x * equ(value),
|
ScaleType.Y => x => value * equ(x),
|
||||||
ScaleType.Both => x => x * equ(value / x),
|
ScaleType.Both => x => value * equ(x / value),
|
||||||
_ => throw new ArgumentException("Unknown scale type " + type)
|
_ => throw new ArgumentException("Unknown scale type " + type)
|
||||||
};
|
};
|
||||||
|
|
||||||
public enum ScaleType
|
|
||||||
{
|
|
||||||
X = 1,
|
|
||||||
Y = 2,
|
|
||||||
Both = X | Y
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Nerd_STF.Graphics;
|
namespace Nerd_STF.Graphics;
|
||||||
|
|
||||||
public struct CMYKA : IColor, IEquatable<CMYKA>
|
public struct CMYKA : IColorFloat, IEquatable<CMYKA>
|
||||||
{
|
{
|
||||||
public static CMYKA Black => new(0, 0, 0, 1);
|
public static CMYKA Black => new(0, 0, 0, 1);
|
||||||
public static CMYKA Blue => new(1, 1, 0, 0);
|
public static CMYKA Blue => new(1, 1, 0, 0);
|
||||||
@ -165,7 +165,7 @@ public struct CMYKA : IColor, IEquatable<CMYKA>
|
|||||||
return (Cs, Ms, Ys, Ks, As);
|
return (Cs, Ms, Ys, Ks, As);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(IColor? col) => col != null && Equals(col.ToCMYKA());
|
public bool Equals(IColorFloat? col) => col != null && Equals(col.ToCMYKA());
|
||||||
public bool Equals(IColorByte? col) => col != null && Equals(col.ToCMYKA());
|
public bool Equals(IColorByte? col) => col != null && Equals(col.ToCMYKA());
|
||||||
public bool Equals(CMYKA col) => A == 0 && col.A == 0 || K == 1 && col.K == 1 || C == col.C && M == col.M
|
public bool Equals(CMYKA col) => A == 0 && col.A == 0 || K == 1 && col.K == 1 || C == col.C && M == col.M
|
||||||
&& Y == col.Y && K == col.K && A == col.A;
|
&& Y == col.Y && K == col.K && A == col.A;
|
||||||
@ -174,9 +174,9 @@ public struct CMYKA : IColor, IEquatable<CMYKA>
|
|||||||
if (obj == null) return base.Equals(obj);
|
if (obj == null) return base.Equals(obj);
|
||||||
Type t = obj.GetType();
|
Type t = obj.GetType();
|
||||||
if (t == typeof(CMYKA)) return Equals((CMYKA)obj);
|
if (t == typeof(CMYKA)) return Equals((CMYKA)obj);
|
||||||
else if (t == typeof(RGBA)) return Equals((IColor)obj);
|
else if (t == typeof(RGBA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(HSVA)) return Equals((IColor)obj);
|
else if (t == typeof(HSVA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(IColor)) return Equals((IColor)obj);
|
else if (t == typeof(IColorFloat)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
||||||
@ -196,7 +196,7 @@ public struct CMYKA : IColor, IEquatable<CMYKA>
|
|||||||
public RGBA ToRGBA()
|
public RGBA ToRGBA()
|
||||||
{
|
{
|
||||||
float kInv = 1 - K, r = 1 - C, g = 1 - M, b = 1 - Y;
|
float kInv = 1 - K, r = 1 - C, g = 1 - M, b = 1 - Y;
|
||||||
return new(r * kInv, g * kInv, b * kInv);
|
return new(r * kInv, g * kInv, b * kInv, A);
|
||||||
}
|
}
|
||||||
public CMYKA ToCMYKA() => this;
|
public CMYKA ToCMYKA() => this;
|
||||||
public HSVA ToHSVA() => ToRGBA().ToHSVA();
|
public HSVA ToHSVA() => ToRGBA().ToHSVA();
|
||||||
|
|||||||
@ -143,7 +143,7 @@ public struct CMYKAByte : IColorByte, IEquatable<CMYKAByte>
|
|||||||
return (Cs, Ms, Ys, Ks, As);
|
return (Cs, Ms, Ys, Ks, As);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(IColor? col) => col != null && Equals(col.ToCMYKAByte());
|
public bool Equals(IColorFloat? col) => col != null && Equals(col.ToCMYKAByte());
|
||||||
public bool Equals(IColorByte? col) => col != null && Equals(col.ToCMYKAByte());
|
public bool Equals(IColorByte? col) => col != null && Equals(col.ToCMYKAByte());
|
||||||
public bool Equals(CMYKAByte col) => A == 0 && col.A == 0 || K == 1 && col.K == 255 || C == col.C && M == col.M
|
public bool Equals(CMYKAByte col) => A == 0 && col.A == 0 || K == 1 && col.K == 255 || C == col.C && M == col.M
|
||||||
&& Y == col.Y && K == col.K && A == col.A;
|
&& Y == col.Y && K == col.K && A == col.A;
|
||||||
@ -152,11 +152,11 @@ public struct CMYKAByte : IColorByte, IEquatable<CMYKAByte>
|
|||||||
if (obj == null) return base.Equals(obj);
|
if (obj == null) return base.Equals(obj);
|
||||||
Type t = obj.GetType();
|
Type t = obj.GetType();
|
||||||
if (t == typeof(CMYKAByte)) return Equals((CMYKAByte)obj);
|
if (t == typeof(CMYKAByte)) return Equals((CMYKAByte)obj);
|
||||||
else if (t == typeof(RGBA)) return Equals((IColor)obj);
|
else if (t == typeof(RGBA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(HSVA)) return Equals((IColor)obj);
|
else if (t == typeof(HSVA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(IColor)) return Equals((IColor)obj);
|
else if (t == typeof(IColorFloat)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(CMYKA)) return Equals((IColor)obj);
|
else if (t == typeof(CMYKA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(IColorByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(IColorByte)) return Equals((IColorByte)obj);
|
||||||
|
|
||||||
@ -174,11 +174,11 @@ public struct CMYKAByte : IColorByte, IEquatable<CMYKAByte>
|
|||||||
|
|
||||||
public RGBA ToRGBA() => ToCMYKA().ToRGBA();
|
public RGBA ToRGBA() => ToCMYKA().ToRGBA();
|
||||||
public CMYKA ToCMYKA() => new(C / 255f, M / 255f, Y / 255f, K / 255f, A / 255f);
|
public CMYKA ToCMYKA() => new(C / 255f, M / 255f, Y / 255f, K / 255f, A / 255f);
|
||||||
public HSVA ToHSVA() => ToRGBA().ToHSVA();
|
public HSVA ToHSVA() => ToCMYKA().ToHSVA();
|
||||||
|
|
||||||
public RGBAByte ToRGBAByte() => ToCMYKA().ToRGBAByte();
|
public RGBAByte ToRGBAByte() => ToCMYKA().ToRGBAByte();
|
||||||
public CMYKAByte ToCMYKAByte() => this;
|
public CMYKAByte ToCMYKAByte() => this;
|
||||||
public HSVAByte ToHSVAByte() => ToRGBA().ToHSVAByte();
|
public HSVAByte ToHSVAByte() => ToCMYKA().ToHSVAByte();
|
||||||
|
|
||||||
public byte[] ToArray() => new[] { C, M, Y, K, A };
|
public byte[] ToArray() => new[] { C, M, Y, K, A };
|
||||||
public Fill<byte> ToFill()
|
public Fill<byte> ToFill()
|
||||||
@ -216,12 +216,12 @@ public struct CMYKAByte : IColorByte, IEquatable<CMYKAByte>
|
|||||||
public static CMYKAByte operator /(CMYKAByte a, int b) =>
|
public static CMYKAByte operator /(CMYKAByte a, int b) =>
|
||||||
new(a.C / b, a.M / b, a.Y / b, a.K / b, a.A / b);
|
new(a.C / b, a.M / b, a.Y / b, a.K / b, a.A / b);
|
||||||
public static CMYKAByte operator /(CMYKAByte a, float b) => (a.ToCMYKA() / b).ToCMYKAByte();
|
public static CMYKAByte operator /(CMYKAByte a, float b) => (a.ToCMYKA() / b).ToCMYKAByte();
|
||||||
public static bool operator ==(CMYKAByte a, RGBA b) => a.Equals((IColor?)b);
|
public static bool operator ==(CMYKAByte a, RGBA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(CMYKAByte a, RGBA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(CMYKAByte a, RGBA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(CMYKAByte a, CMYKA b) => a.Equals((IColor?)b);
|
public static bool operator ==(CMYKAByte a, CMYKA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(CMYKAByte a, CMYKA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(CMYKAByte a, CMYKA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(CMYKAByte a, HSVA b) => a.Equals((IColor?)b);
|
public static bool operator ==(CMYKAByte a, HSVA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(CMYKAByte a, HSVA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(CMYKAByte a, HSVA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(CMYKAByte a, RGBAByte b) => a.Equals(b);
|
public static bool operator ==(CMYKAByte a, RGBAByte b) => a.Equals(b);
|
||||||
public static bool operator !=(CMYKAByte a, RGBAByte b) => !a.Equals(b);
|
public static bool operator !=(CMYKAByte a, RGBAByte b) => !a.Equals(b);
|
||||||
public static bool operator ==(CMYKAByte a, CMYKAByte b) => a.Equals(b);
|
public static bool operator ==(CMYKAByte a, CMYKAByte b) => a.Equals(b);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Nerd_STF.Graphics;
|
namespace Nerd_STF.Graphics;
|
||||||
|
|
||||||
public struct HSVA : IColor, IEquatable<HSVA>
|
public struct HSVA : IColorFloat, IEquatable<HSVA>
|
||||||
{
|
{
|
||||||
public static HSVA Black => new(Angle.Zero, 0, 0);
|
public static HSVA Black => new(Angle.Zero, 0, 0);
|
||||||
public static HSVA Blue => new(new Angle(240), 1, 1);
|
public static HSVA Blue => new(new Angle(240), 1, 1);
|
||||||
@ -159,7 +159,7 @@ public struct HSVA : IColor, IEquatable<HSVA>
|
|||||||
return (Hs, Ss, Vs, As);
|
return (Hs, Ss, Vs, As);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(IColor? col) => col != null && Equals(col.ToHSVA());
|
public bool Equals(IColorFloat? col) => col != null && Equals(col.ToHSVA());
|
||||||
public bool Equals(IColorByte? col) => col != null && Equals(col.ToHSVA());
|
public bool Equals(IColorByte? col) => col != null && Equals(col.ToHSVA());
|
||||||
public bool Equals(HSVA col) => S == 0 && col.S == 0 || V == 0 && col.V == 0 || A == 0 && col.A == 0
|
public bool Equals(HSVA col) => S == 0 && col.S == 0 || V == 0 && col.V == 0 || A == 0 && col.A == 0
|
||||||
|| H == col.H && S == col.S && V == col.V && A == col.A;
|
|| H == col.H && S == col.S && V == col.V && A == col.A;
|
||||||
@ -168,9 +168,9 @@ public struct HSVA : IColor, IEquatable<HSVA>
|
|||||||
if (obj == null) return base.Equals(obj);
|
if (obj == null) return base.Equals(obj);
|
||||||
Type t = obj.GetType();
|
Type t = obj.GetType();
|
||||||
if (t == typeof(HSVA)) return Equals((HSVA)obj);
|
if (t == typeof(HSVA)) return Equals((HSVA)obj);
|
||||||
else if (t == typeof(CMYKA)) return Equals((IColor)obj);
|
else if (t == typeof(CMYKA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(RGBA)) return Equals((IColor)obj);
|
else if (t == typeof(RGBA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(IColor)) return Equals((IColor)obj);
|
else if (t == typeof(IColorFloat)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
||||||
@ -195,7 +195,7 @@ public struct HSVA : IColor, IEquatable<HSVA>
|
|||||||
else if (d < 240) vals = (0, x, c);
|
else if (d < 240) vals = (0, x, c);
|
||||||
else if (d < 300) vals = (x, 0, c);
|
else if (d < 300) vals = (x, 0, c);
|
||||||
else if (d < 360) vals = (c, 0, x);
|
else if (d < 360) vals = (c, 0, x);
|
||||||
return new(vals.r + m, vals.g + m, vals.b + m);
|
return new(vals.r + m, vals.g + m, vals.b + m, A);
|
||||||
}
|
}
|
||||||
public CMYKA ToCMYKA() => ToRGBA().ToCMYKA();
|
public CMYKA ToCMYKA() => ToRGBA().ToCMYKA();
|
||||||
public HSVA ToHSVA() => this;
|
public HSVA ToHSVA() => this;
|
||||||
|
|||||||
@ -130,7 +130,7 @@ public struct HSVAByte : IColorByte, IEquatable<HSVAByte>
|
|||||||
return (Hs, Ss, Vs, As);
|
return (Hs, Ss, Vs, As);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(IColor? col) => col != null && Equals(col.ToHSVAByte());
|
public bool Equals(IColorFloat? col) => col != null && Equals(col.ToHSVAByte());
|
||||||
public bool Equals(IColorByte? col) => col != null && Equals(col.ToHSVAByte());
|
public bool Equals(IColorByte? col) => col != null && Equals(col.ToHSVAByte());
|
||||||
public bool Equals(HSVAByte col) => S == 0 && col.S == 0 || V == 0 && col.V == 0 || A == 0 && col.A == 0
|
public bool Equals(HSVAByte col) => S == 0 && col.S == 0 || V == 0 && col.V == 0 || A == 0 && col.A == 0
|
||||||
|| H == col.H && S == col.S && V == col.V && A == col.A;
|
|| H == col.H && S == col.S && V == col.V && A == col.A;
|
||||||
@ -139,12 +139,12 @@ public struct HSVAByte : IColorByte, IEquatable<HSVAByte>
|
|||||||
if (obj == null) return base.Equals(obj);
|
if (obj == null) return base.Equals(obj);
|
||||||
Type t = obj.GetType();
|
Type t = obj.GetType();
|
||||||
if (t == typeof(HSVAByte)) return Equals((HSVAByte)obj);
|
if (t == typeof(HSVAByte)) return Equals((HSVAByte)obj);
|
||||||
else if (t == typeof(CMYKA)) return Equals((IColor)obj);
|
else if (t == typeof(CMYKA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(RGBA)) return Equals((IColor)obj);
|
else if (t == typeof(RGBA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(IColor)) return Equals((IColor)obj);
|
else if (t == typeof(IColorFloat)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(HSVA)) return Equals((IColor)obj);
|
else if (t == typeof(HSVA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(IColorByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(IColorByte)) return Equals((IColorByte)obj);
|
||||||
|
|
||||||
return base.Equals(obj);
|
return base.Equals(obj);
|
||||||
@ -192,12 +192,12 @@ public struct HSVAByte : IColorByte, IEquatable<HSVAByte>
|
|||||||
public static HSVAByte operator /(HSVAByte a, HSVAByte b) => new(a.H / b.H, a.S / b.S, a.V / b.V, a.A / b.A);
|
public static HSVAByte operator /(HSVAByte a, HSVAByte b) => new(a.H / b.H, a.S / b.S, a.V / b.V, a.A / b.A);
|
||||||
public static HSVAByte operator /(HSVAByte a, int b) => new(a.H / b, a.S / b, a.V / b, a.A / b);
|
public static HSVAByte operator /(HSVAByte a, int b) => new(a.H / b, a.S / b, a.V / b, a.A / b);
|
||||||
public static HSVAByte operator /(HSVAByte a, float b) => (a.ToHSVA() * b).ToHSVAByte();
|
public static HSVAByte operator /(HSVAByte a, float b) => (a.ToHSVA() * b).ToHSVAByte();
|
||||||
public static bool operator ==(HSVAByte a, RGBA b) => a.Equals((IColor?)b);
|
public static bool operator ==(HSVAByte a, RGBA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(HSVAByte a, RGBA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(HSVAByte a, RGBA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(HSVAByte a, CMYKA b) => a.Equals((IColor?)b);
|
public static bool operator ==(HSVAByte a, CMYKA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(HSVAByte a, CMYKA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(HSVAByte a, CMYKA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(HSVAByte a, HSVA b) => a.Equals((IColor?)b);
|
public static bool operator ==(HSVAByte a, HSVA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(HSVAByte a, HSVA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(HSVAByte a, HSVA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(HSVAByte a, RGBAByte b) => a.Equals(b);
|
public static bool operator ==(HSVAByte a, RGBAByte b) => a.Equals(b);
|
||||||
public static bool operator !=(HSVAByte a, RGBAByte b) => !a.Equals(b);
|
public static bool operator !=(HSVAByte a, RGBAByte b) => !a.Equals(b);
|
||||||
public static bool operator ==(HSVAByte a, CMYKAByte b) => a.Equals(b);
|
public static bool operator ==(HSVAByte a, CMYKAByte b) => a.Equals(b);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Nerd_STF.Graphics;
|
namespace Nerd_STF.Graphics;
|
||||||
|
|
||||||
public interface IColor : ICloneable, IEquatable<IColor?>, IEquatable<IColorByte?>, IGroup<float>
|
public interface IColor : ICloneable, IEquatable<IColorFloat?>, IEquatable<IColorByte?>
|
||||||
{
|
{
|
||||||
public RGBA ToRGBA();
|
public RGBA ToRGBA();
|
||||||
public CMYKA ToCMYKA();
|
public CMYKA ToCMYKA();
|
||||||
|
|||||||
@ -1,12 +1,3 @@
|
|||||||
namespace Nerd_STF.Graphics;
|
namespace Nerd_STF.Graphics;
|
||||||
|
|
||||||
public interface IColorByte : ICloneable, IEquatable<IColor?>, IEquatable<IColorByte?>, IGroup<byte>
|
public interface IColorByte : IColor, IGroup<byte> { }
|
||||||
{
|
|
||||||
public RGBA ToRGBA();
|
|
||||||
public CMYKA ToCMYKA();
|
|
||||||
public HSVA ToHSVA();
|
|
||||||
|
|
||||||
public RGBAByte ToRGBAByte();
|
|
||||||
public CMYKAByte ToCMYKAByte();
|
|
||||||
public HSVAByte ToHSVAByte();
|
|
||||||
}
|
|
||||||
|
|||||||
3
Nerd_STF/Graphics/IColorFloat.cs
Normal file
3
Nerd_STF/Graphics/IColorFloat.cs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
namespace Nerd_STF.Graphics;
|
||||||
|
|
||||||
|
public interface IColorFloat : IColor, IGroup<float> { }
|
||||||
@ -15,12 +15,13 @@ public struct Image : ICloneable, IEnumerable, IEquatable<Image>
|
|||||||
{
|
{
|
||||||
Pixels = new IColor[width, height];
|
Pixels = new IColor[width, height];
|
||||||
Size = new(width, height);
|
Size = new(width, height);
|
||||||
for (int y = 0; y < width; y++) for (int x = 0; x < height; x++) Pixels[x, y] = cols[y * width + x];
|
for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) Pixels[x, y] = cols[y * width + x];
|
||||||
}
|
}
|
||||||
public Image(int width, int height, IColor[,] cols)
|
public Image(int width, int height, IColor[,] cols)
|
||||||
{
|
{
|
||||||
Pixels = cols;
|
Pixels = new IColor[width, height];
|
||||||
Size = new(width, height);
|
Size = new(width, height);
|
||||||
|
for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) Pixels[x, y] = cols[y, x];
|
||||||
}
|
}
|
||||||
public Image(int width, int height, Fill<IColor> fill)
|
public Image(int width, int height, Fill<IColor> fill)
|
||||||
{
|
{
|
||||||
@ -32,28 +33,13 @@ public struct Image : ICloneable, IEnumerable, IEquatable<Image>
|
|||||||
{
|
{
|
||||||
Pixels = new IColor[width, height];
|
Pixels = new IColor[width, height];
|
||||||
Size = new(width, height);
|
Size = new(width, height);
|
||||||
for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) Pixels[x, y] = fill(x, y);
|
for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) Pixels[x, y] = fill(y, x);
|
||||||
}
|
|
||||||
public Image(int width, int height, Fill<IColorByte> fill)
|
|
||||||
{
|
|
||||||
Pixels = new IColor[width, height];
|
|
||||||
Size = new(width, height);
|
|
||||||
for (int y = 0; y < height; y++) for (int x = 0; x < width; x++)
|
|
||||||
Pixels[x, y] = (IColor)fill(y * width + x);
|
|
||||||
}
|
|
||||||
public Image(int width, int height, Fill2D<IColorByte> fill)
|
|
||||||
{
|
|
||||||
Pixels = new IColor[width, height];
|
|
||||||
Size = new(width, height);
|
|
||||||
for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) Pixels[x, y] = (IColor)fill(x, y);
|
|
||||||
}
|
}
|
||||||
public Image(Int2 size) : this(size.x, size.y) { }
|
public Image(Int2 size) : this(size.x, size.y) { }
|
||||||
public Image(Int2 size, IColor[] cols) : this(size.x, size.y, cols) { }
|
public Image(Int2 size, IColor[] cols) : this(size.x, size.y, cols) { }
|
||||||
public Image(Int2 size, IColor[,] cols) : this(size.x, size.y, cols) { }
|
public Image(Int2 size, IColor[,] cols) : this(size.x, size.y, cols) { }
|
||||||
public Image(Int2 size, Fill<IColor> fill) : this(size.x, size.y, fill) { }
|
public Image(Int2 size, Fill<IColor> fill) : this(size.x, size.y, fill) { }
|
||||||
public Image(Int2 size, Fill2D<IColor> fill) : this(size.x, size.y, fill) { }
|
public Image(Int2 size, Fill2D<IColor> fill) : this(size.x, size.y, fill) { }
|
||||||
public Image(Int2 size, Fill<IColorByte> fill) : this(size.x, size.y, fill) { }
|
|
||||||
public Image(Int2 size, Fill2D<IColorByte> fill) : this(size.x, size.y, fill) { }
|
|
||||||
|
|
||||||
public IColor this[int indexX, int indexY]
|
public IColor this[int indexX, int indexY]
|
||||||
{
|
{
|
||||||
@ -124,7 +110,7 @@ public struct Image : ICloneable, IEnumerable, IEquatable<Image>
|
|||||||
for (int y = 0; y < Size.y; y++) for (int x = 0; x < Size.x; x++)
|
for (int y = 0; y < Size.y; y++) for (int x = 0; x < Size.x; x++)
|
||||||
{
|
{
|
||||||
HSVA col = Pixels[x, y].ToHSVA();
|
HSVA col = Pixels[x, y].ToHSVA();
|
||||||
col.S = (set ? 0 : col.S) + value;
|
col.S = (set ? 0 : col.S) * value;
|
||||||
Pixels[x, y] = col;
|
Pixels[x, y] = col;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -144,7 +130,7 @@ public struct Image : ICloneable, IEnumerable, IEquatable<Image>
|
|||||||
for (int y = 0; y < newSize.y; y++) for (int x = 0; x < newSize.x; x++)
|
for (int y = 0; y < newSize.y; y++) for (int x = 0; x < newSize.x; x++)
|
||||||
{
|
{
|
||||||
Float2 f = new((float)x / newSize.x, (float)y / newSize.y);
|
Float2 f = new((float)x / newSize.x, (float)y / newSize.y);
|
||||||
RGBA col = Pixels[Mathf.RoundInt(f.x * Size.x), Mathf.RoundInt(f.y * Size.y)].ToRGBA();
|
RGBA col = Pixels[Mathf.Floor(f.x * Size.x), Mathf.Floor(f.y * Size.y)].ToRGBA();
|
||||||
img[x, y] = col;
|
img[x, y] = col;
|
||||||
}
|
}
|
||||||
this = img;
|
this = img;
|
||||||
|
|||||||
@ -5,17 +5,17 @@ public struct Material : ICloneable, IEquatable<Material>
|
|||||||
public float Alpha;
|
public float Alpha;
|
||||||
public float Anisotropy;
|
public float Anisotropy;
|
||||||
public float AnisotropyRoughness;
|
public float AnisotropyRoughness;
|
||||||
public IColor AmbientColor;
|
public IColorFloat AmbientColor;
|
||||||
public float ClearcoatRoughness;
|
public float ClearcoatRoughness;
|
||||||
public float ClearcoatThickness;
|
public float ClearcoatThickness;
|
||||||
public IColor DiffuseColor;
|
public IColorFloat DiffuseColor;
|
||||||
public IColor Emissive;
|
public IColorFloat Emissive;
|
||||||
public IlluminationModel IllumModel;
|
public IlluminationModel IllumModel;
|
||||||
public float Metallic;
|
public float Metallic;
|
||||||
public float OpticalDensity;
|
public float OpticalDensity;
|
||||||
public float Roughness;
|
public float Roughness;
|
||||||
public float Sheen;
|
public float Sheen;
|
||||||
public IColor SpecularColor;
|
public IColorFloat SpecularColor;
|
||||||
public float SpecularExponent;
|
public float SpecularExponent;
|
||||||
|
|
||||||
public (Image Image, TextureConfig Config) AlphaTexture;
|
public (Image Image, TextureConfig Config) AlphaTexture;
|
||||||
@ -67,17 +67,17 @@ public struct Material : ICloneable, IEquatable<Material>
|
|||||||
Alpha = (float)fill(0);
|
Alpha = (float)fill(0);
|
||||||
Anisotropy = (float)fill(1);
|
Anisotropy = (float)fill(1);
|
||||||
AnisotropyRoughness = (float)fill(2);
|
AnisotropyRoughness = (float)fill(2);
|
||||||
AmbientColor = (IColor)fill(3);
|
AmbientColor = (IColorFloat)fill(3);
|
||||||
ClearcoatRoughness = (float)fill(4);
|
ClearcoatRoughness = (float)fill(4);
|
||||||
ClearcoatThickness = (float)fill(5);
|
ClearcoatThickness = (float)fill(5);
|
||||||
DiffuseColor = (IColor)fill(6);
|
DiffuseColor = (IColorFloat)fill(6);
|
||||||
Emissive = (IColor)fill(7);
|
Emissive = (IColorFloat)fill(7);
|
||||||
IllumModel = (IlluminationModel)fill(8);
|
IllumModel = (IlluminationModel)fill(8);
|
||||||
Metallic = (float)fill(9);
|
Metallic = (float)fill(9);
|
||||||
OpticalDensity = (float)fill(10);
|
OpticalDensity = (float)fill(10);
|
||||||
Roughness = (float)fill(11);
|
Roughness = (float)fill(11);
|
||||||
Sheen = (float)fill(12);
|
Sheen = (float)fill(12);
|
||||||
SpecularColor = (IColor)fill(13);
|
SpecularColor = (IColorFloat)fill(13);
|
||||||
SpecularExponent = (float)fill(14);
|
SpecularExponent = (float)fill(14);
|
||||||
|
|
||||||
AlphaTexture = ((Image, TextureConfig))fill(15);
|
AlphaTexture = ((Image, TextureConfig))fill(15);
|
||||||
@ -93,7 +93,7 @@ public struct Material : ICloneable, IEquatable<Material>
|
|||||||
SpecularHighlightTexture = ((Image, TextureConfig))fill(25);
|
SpecularHighlightTexture = ((Image, TextureConfig))fill(25);
|
||||||
StencilTexture = ((Image, TextureConfig))fill(26);
|
StencilTexture = ((Image, TextureConfig))fill(26);
|
||||||
}
|
}
|
||||||
public Material(IlluminationModel illum, Fill<float> floats, Fill<IColor> colors, Fill<(Image, TextureConfig)> images)
|
public Material(IlluminationModel illum, Fill<float> floats, Fill<IColorFloat> colors, Fill<(Image, TextureConfig)> images)
|
||||||
{
|
{
|
||||||
Alpha = floats(0);
|
Alpha = floats(0);
|
||||||
Anisotropy = floats(1);
|
Anisotropy = floats(1);
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
namespace Nerd_STF.Graphics;
|
namespace Nerd_STF.Graphics;
|
||||||
|
|
||||||
public struct RGBA : IColor, IEquatable<RGBA>
|
public struct RGBA : IColorFloat, IEquatable<RGBA>
|
||||||
{
|
{
|
||||||
public static RGBA Black => new(0, 0, 0);
|
public static RGBA Black => new(0, 0, 0);
|
||||||
public static RGBA Blue => new(0, 0, 1);
|
public static RGBA Blue => new(0, 0, 1);
|
||||||
@ -149,7 +149,7 @@ public struct RGBA : IColor, IEquatable<RGBA>
|
|||||||
return (Rs, Gs, Bs, As);
|
return (Rs, Gs, Bs, As);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(IColor? col) => col != null && Equals(col.ToRGBA());
|
public bool Equals(IColorFloat? col) => col != null && Equals(col.ToRGBA());
|
||||||
public bool Equals(IColorByte? col) => col != null && Equals(col.ToRGBA());
|
public bool Equals(IColorByte? col) => col != null && Equals(col.ToRGBA());
|
||||||
public bool Equals(RGBA col) => A == 0 && col.A == 0 || R == col.R && G == col.G && B == col.B && A == col.A;
|
public bool Equals(RGBA col) => A == 0 && col.A == 0 || R == col.R && G == col.G && B == col.B && A == col.A;
|
||||||
public override bool Equals([NotNullWhen(true)] object? obj)
|
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||||
@ -157,9 +157,9 @@ public struct RGBA : IColor, IEquatable<RGBA>
|
|||||||
if (obj == null) return base.Equals(obj);
|
if (obj == null) return base.Equals(obj);
|
||||||
Type t = obj.GetType();
|
Type t = obj.GetType();
|
||||||
if (t == typeof(RGBA)) return Equals((RGBA)obj);
|
if (t == typeof(RGBA)) return Equals((RGBA)obj);
|
||||||
else if (t == typeof(CMYKA)) return Equals((IColor)obj);
|
else if (t == typeof(CMYKA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(HSVA)) return Equals((IColor)obj);
|
else if (t == typeof(HSVA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(IColor)) return Equals((IColor)obj);
|
else if (t == typeof(IColorFloat)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(RGBAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
||||||
|
|||||||
@ -132,7 +132,7 @@ public struct RGBAByte : IColorByte, IEquatable<RGBAByte>
|
|||||||
return (Rs, Gs, Bs, As);
|
return (Rs, Gs, Bs, As);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(IColor? col) => col != null && Equals(col.ToRGBAByte());
|
public bool Equals(IColorFloat? col) => col != null && Equals(col.ToRGBAByte());
|
||||||
public bool Equals(IColorByte? col) => col != null && Equals(col.ToRGBAByte());
|
public bool Equals(IColorByte? col) => col != null && Equals(col.ToRGBAByte());
|
||||||
public bool Equals(RGBAByte col) => A == 0 && col.A == 0 || R == col.R && G == col.G && B == col.B && A == col.A;
|
public bool Equals(RGBAByte col) => A == 0 && col.A == 0 || R == col.R && G == col.G && B == col.B && A == col.A;
|
||||||
public override bool Equals([NotNullWhen(true)] object? obj)
|
public override bool Equals([NotNullWhen(true)] object? obj)
|
||||||
@ -140,9 +140,9 @@ public struct RGBAByte : IColorByte, IEquatable<RGBAByte>
|
|||||||
if (obj == null) return base.Equals(obj);
|
if (obj == null) return base.Equals(obj);
|
||||||
Type t = obj.GetType();
|
Type t = obj.GetType();
|
||||||
if (t == typeof(RGBAByte)) return Equals((RGBAByte)obj);
|
if (t == typeof(RGBAByte)) return Equals((RGBAByte)obj);
|
||||||
else if (t == typeof(CMYKA)) return Equals((IColor)obj);
|
else if (t == typeof(CMYKA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(HSVA)) return Equals((IColor)obj);
|
else if (t == typeof(HSVA)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(IColor)) return Equals((IColor)obj);
|
else if (t == typeof(IColorFloat)) return Equals((IColorFloat)obj);
|
||||||
else if (t == typeof(RGBA)) return Equals((IColorByte)obj);
|
else if (t == typeof(RGBA)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(CMYKAByte)) return Equals((IColorByte)obj);
|
||||||
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
else if (t == typeof(HSVAByte)) return Equals((IColorByte)obj);
|
||||||
@ -195,12 +195,12 @@ public struct RGBAByte : IColorByte, IEquatable<RGBAByte>
|
|||||||
public static RGBAByte operator /(RGBAByte a, RGBAByte b) => new(a.R / b.R, a.G / b.G, a.B / b.B, a.A / b.A);
|
public static RGBAByte operator /(RGBAByte a, RGBAByte b) => new(a.R / b.R, a.G / b.G, a.B / b.B, a.A / b.A);
|
||||||
public static RGBAByte operator /(RGBAByte a, int b) => new(a.R / b, a.G / b, a.B / b, a.A / b);
|
public static RGBAByte operator /(RGBAByte a, int b) => new(a.R / b, a.G / b, a.B / b, a.A / b);
|
||||||
public static RGBAByte operator /(RGBAByte a, float b) => (a.ToRGBA() / b).ToRGBAByte();
|
public static RGBAByte operator /(RGBAByte a, float b) => (a.ToRGBA() / b).ToRGBAByte();
|
||||||
public static bool operator ==(RGBAByte a, RGBA b) => a.Equals((IColor?)b);
|
public static bool operator ==(RGBAByte a, RGBA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(RGBAByte a, RGBA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(RGBAByte a, RGBA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(RGBAByte a, CMYKA b) => a.Equals((IColor?)b);
|
public static bool operator ==(RGBAByte a, CMYKA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(RGBAByte a, CMYKA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(RGBAByte a, CMYKA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(RGBAByte a, HSVA b) => a.Equals((IColor?)b);
|
public static bool operator ==(RGBAByte a, HSVA b) => a.Equals((IColorFloat?)b);
|
||||||
public static bool operator !=(RGBAByte a, HSVA b) => !a.Equals((IColor?)b);
|
public static bool operator !=(RGBAByte a, HSVA b) => !a.Equals((IColorFloat?)b);
|
||||||
public static bool operator ==(RGBAByte a, RGBAByte b) => a.Equals(b);
|
public static bool operator ==(RGBAByte a, RGBAByte b) => a.Equals(b);
|
||||||
public static bool operator !=(RGBAByte a, RGBAByte b) => !a.Equals(b);
|
public static bool operator !=(RGBAByte a, RGBAByte b) => !a.Equals(b);
|
||||||
public static bool operator ==(RGBAByte a, CMYKAByte b) => a.Equals(b);
|
public static bool operator ==(RGBAByte a, CMYKAByte b) => a.Equals(b);
|
||||||
|
|||||||
@ -107,7 +107,7 @@ public struct Vector2d : ICloneable, IComparable<Vector2d>, IEquatable<Vector2d>
|
|||||||
public bool Equals(Vector2d other) => theta == other.theta && magnitude == other.magnitude;
|
public bool Equals(Vector2d other) => theta == other.theta && magnitude == other.magnitude;
|
||||||
public override int GetHashCode() => theta.GetHashCode() ^ magnitude.GetHashCode();
|
public override int GetHashCode() => theta.GetHashCode() ^ magnitude.GetHashCode();
|
||||||
public override string ToString() => ToString((string?)null);
|
public override string ToString() => ToString((string?)null);
|
||||||
public string ToString(Angle.Type outputType = Angle.Type.Degrees) => ToString((string?)null, outputType);
|
public string ToString(Angle.Type outputType) => ToString((string?)null, outputType);
|
||||||
public string ToString(string? provider, Angle.Type outputType = Angle.Type.Degrees) =>
|
public string ToString(string? provider, Angle.Type outputType = Angle.Type.Degrees) =>
|
||||||
"Mag: " + magnitude.ToString(provider) + " Rot: " + theta.ToString(provider, outputType);
|
"Mag: " + magnitude.ToString(provider) + " Rot: " + theta.ToString(provider, outputType);
|
||||||
public string ToString(IFormatProvider provider, Angle.Type outputType = Angle.Type.Degrees) =>
|
public string ToString(IFormatProvider provider, Angle.Type outputType = Angle.Type.Degrees) =>
|
||||||
|
|||||||
@ -145,15 +145,20 @@ public struct Vector3d : ICloneable, IComparable<Vector3d>, IEquatable<Vector3d>
|
|||||||
public bool Equals(Vector3d other) => yaw == other.yaw && pitch == other.pitch
|
public bool Equals(Vector3d other) => yaw == other.yaw && pitch == other.pitch
|
||||||
&& magnitude == other.magnitude;
|
&& magnitude == other.magnitude;
|
||||||
public override int GetHashCode() => yaw.GetHashCode() ^ pitch.GetHashCode() ^ magnitude.GetHashCode();
|
public override int GetHashCode() => yaw.GetHashCode() ^ pitch.GetHashCode() ^ magnitude.GetHashCode();
|
||||||
|
public override string ToString() => ToString((string?)null);
|
||||||
|
public string ToString(Angle.Type outputType) => ToString((string?)null, outputType);
|
||||||
public string ToString(string? provider, Angle.Type outputType = Angle.Type.Degrees) =>
|
public string ToString(string? provider, Angle.Type outputType = Angle.Type.Degrees) =>
|
||||||
"Mag: " + magnitude.ToString(provider) + " Theta: " + yaw.ToString(provider, outputType) +
|
"Mag: " + magnitude.ToString(provider) + " Yaw: " + yaw.ToString(provider, outputType) +
|
||||||
" Phi: " + pitch.ToString(provider, outputType);
|
" Pitch: " + pitch.ToString(provider, outputType);
|
||||||
|
public string ToString(IFormatProvider provider, Angle.Type outputType = Angle.Type.Degrees) =>
|
||||||
|
"Mag: " + magnitude.ToString(provider) + " Yaw: " + yaw.ToString(provider, outputType) +
|
||||||
|
" Pitch: " + pitch.ToString(provider, outputType);
|
||||||
|
|
||||||
public object Clone() => new Vector3d(yaw, pitch, magnitude);
|
public object Clone() => new Vector3d(yaw, pitch, magnitude);
|
||||||
|
|
||||||
public Float3 ToXYZ() => new(Mathf.Sin(pitch) * Mathf.Cos(yaw) * magnitude,
|
public Float3 ToXYZ() => new Float3(Mathf.Sin(pitch) * Mathf.Sin(yaw),
|
||||||
Mathf.Sin(pitch) * Mathf.Sin(yaw) * magnitude,
|
Mathf.Cos(yaw),
|
||||||
Mathf.Cos(pitch) * magnitude);
|
Mathf.Cos(pitch) * Mathf.Sin(yaw)) * magnitude;
|
||||||
|
|
||||||
public static Vector3d operator +(Vector3d a, Vector3d b) => new(a.yaw + b.yaw, a.pitch + b.pitch,
|
public static Vector3d operator +(Vector3d a, Vector3d b) => new(a.yaw + b.yaw, a.pitch + b.pitch,
|
||||||
a.magnitude + b.magnitude);
|
a.magnitude + b.magnitude);
|
||||||
|
|||||||
@ -35,6 +35,8 @@ public struct Angle : ICloneable, IComparable<Angle>, IEquatable<Angle>
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Angle Bounded => new(Mathf.AbsoluteMod(p_deg, 360));
|
public Angle Bounded => new(Mathf.AbsoluteMod(p_deg, 360));
|
||||||
|
public Angle Complimentary => Quarter - this;
|
||||||
|
public Angle Supplementary => Half - this;
|
||||||
public Angle Reflected => new Angle(-p_deg).Bounded;
|
public Angle Reflected => new Angle(-p_deg).Bounded;
|
||||||
|
|
||||||
private float p_deg;
|
private float p_deg;
|
||||||
|
|||||||
@ -174,6 +174,7 @@ public struct Float2 : ICloneable, IComparable<Float2>, IEquatable<Float2>, IGro
|
|||||||
public static Float2 operator *(Float2 a, Float2 b) => new(a.x * b.x, a.y * b.y);
|
public static Float2 operator *(Float2 a, Float2 b) => new(a.x * b.x, a.y * b.y);
|
||||||
public static Float2 operator *(Float2 a, float b) => new(a.x * b, a.y * b);
|
public static Float2 operator *(Float2 a, float b) => new(a.x * b, a.y * b);
|
||||||
public static Float2 operator *(Float2 a, Matrix b) => (Float2)((Matrix)a * b);
|
public static Float2 operator *(Float2 a, Matrix b) => (Float2)((Matrix)a * b);
|
||||||
|
public static Quaternion operator *(Float2 a, Quaternion b) => (Quaternion)a * b;
|
||||||
public static Float2 operator /(Float2 a, Float2 b) => new(a.x / b.x, a.y / b.y);
|
public static Float2 operator /(Float2 a, Float2 b) => new(a.x / b.x, a.y / b.y);
|
||||||
public static Float2 operator /(Float2 a, float b) => new(a.x / b, a.y / b);
|
public static Float2 operator /(Float2 a, float b) => new(a.x / b, a.y / b);
|
||||||
public static Float2 operator /(Float2 a, Matrix b) => (Float2)((Matrix)a / b);
|
public static Float2 operator /(Float2 a, Matrix b) => (Float2)((Matrix)a / b);
|
||||||
|
|||||||
@ -191,7 +191,10 @@ public struct Float3 : ICloneable, IComparable<Float3>, IEquatable<Float3>, IGro
|
|||||||
public Vector3d ToVector()
|
public Vector3d ToVector()
|
||||||
{
|
{
|
||||||
float mag = Magnitude;
|
float mag = Magnitude;
|
||||||
return new(Mathf.ArcTan(y / x), Mathf.ArcCos(z / mag), mag);
|
Float3 normalized = Normalized;
|
||||||
|
Angle yaw = Mathf.ArcCos(normalized.y);
|
||||||
|
Angle pitch = Mathf.ArcSin(normalized.x / Mathf.Sin(yaw));
|
||||||
|
return new(yaw, pitch, mag);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Float3 operator +(Float3 a, Float3 b) => new(a.x + b.x, a.y + b.y, a.z + b.z);
|
public static Float3 operator +(Float3 a, Float3 b) => new(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||||
@ -200,6 +203,7 @@ public struct Float3 : ICloneable, IComparable<Float3>, IEquatable<Float3>, IGro
|
|||||||
public static Float3 operator *(Float3 a, Float3 b) => new(a.x * b.x, a.y * b.y, a.z * b.z);
|
public static Float3 operator *(Float3 a, Float3 b) => new(a.x * b.x, a.y * b.y, a.z * b.z);
|
||||||
public static Float3 operator *(Float3 a, float b) => new(a.x * b, a.y * b, a.z * b);
|
public static Float3 operator *(Float3 a, float b) => new(a.x * b, a.y * b, a.z * b);
|
||||||
public static Float3 operator *(Float3 a, Matrix b) => (Float3)((Matrix)a * b);
|
public static Float3 operator *(Float3 a, Matrix b) => (Float3)((Matrix)a * b);
|
||||||
|
public static Quaternion operator *(Float3 a, Quaternion b) => (Quaternion)a * b;
|
||||||
public static Float3 operator /(Float3 a, Float3 b) => new(a.x / b.x, a.y / b.y, a.z / b.z);
|
public static Float3 operator /(Float3 a, Float3 b) => new(a.x / b.x, a.y / b.y, a.z / b.z);
|
||||||
public static Float3 operator /(Float3 a, float b) => new(a.x / b, a.y / b, a.z / b);
|
public static Float3 operator /(Float3 a, float b) => new(a.x / b, a.y / b, a.z / b);
|
||||||
public static Float3 operator /(Float3 a, Matrix b) => (Float3)((Matrix)a / b);
|
public static Float3 operator /(Float3 a, Matrix b) => (Float3)((Matrix)a / b);
|
||||||
|
|||||||
@ -8,6 +8,12 @@ public interface ITriangulatable
|
|||||||
foreach (ITriangulatable triangulatable in triangulatables) res.AddRange(triangulatable.Triangulate());
|
foreach (ITriangulatable triangulatable in triangulatables) res.AddRange(triangulatable.Triangulate());
|
||||||
return res.ToArray();
|
return res.ToArray();
|
||||||
}
|
}
|
||||||
|
public static Triangle[] TriangulateAll<T>(params T[] triangulatables) where T : ITriangulatable
|
||||||
|
{
|
||||||
|
List<Triangle> res = new();
|
||||||
|
foreach (ITriangulatable triangulatable in triangulatables) res.AddRange(triangulatable.Triangulate());
|
||||||
|
return res.ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
public Triangle[] Triangulate();
|
public Triangle[] Triangulate();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -170,6 +170,7 @@ public struct Complex : ICloneable, IComparable<Complex>, IEquatable<Complex>, I
|
|||||||
public static Complex operator /(Complex a, Complex b) => a * b.Inverse;
|
public static Complex operator /(Complex a, Complex b) => a * b.Inverse;
|
||||||
public static Complex operator /(Complex a, float b) => new(a.u / b, a.i / b);
|
public static Complex operator /(Complex a, float b) => new(a.u / b, a.i / b);
|
||||||
public static Complex operator /(Complex a, Matrix b) => (Complex)((Matrix)a / b);
|
public static Complex operator /(Complex a, Matrix b) => (Complex)((Matrix)a / b);
|
||||||
|
public static Complex operator ~(Complex v) => v.Conjugate;
|
||||||
public static bool operator ==(Complex a, Complex b) => a.Equals(b);
|
public static bool operator ==(Complex a, Complex b) => a.Equals(b);
|
||||||
public static bool operator !=(Complex a, Complex b) => !a.Equals(b);
|
public static bool operator !=(Complex a, Complex b) => !a.Equals(b);
|
||||||
public static bool operator >(Complex a, Complex b) => a.CompareTo(b) > 0;
|
public static bool operator >(Complex a, Complex b) => a.CompareTo(b) > 0;
|
||||||
|
|||||||
@ -14,12 +14,21 @@ public struct Quaternion : ICloneable, IComparable<Quaternion>, IEquatable<Quate
|
|||||||
public static Quaternion One => new(1, 1, 1, 1);
|
public static Quaternion One => new(1, 1, 1, 1);
|
||||||
public static Quaternion Zero => new(0, 0, 0, 0);
|
public static Quaternion Zero => new(0, 0, 0, 0);
|
||||||
|
|
||||||
public Quaternion Conjugate => new(u, -i, -j, -k);
|
public Quaternion Conjugate => new(u, -IJK);
|
||||||
public Quaternion Inverse => Conjugate / (u * u + i * i + j * j + k * k);
|
public Quaternion Inverse => Conjugate / (u * u + i * i + j * j + k * k);
|
||||||
public float Magnitude => Mathf.Sqrt(u * u + i * i + j * j + k * k);
|
public float Magnitude => Mathf.Sqrt(u * u + i * i + j * j + k * k);
|
||||||
public Quaternion Normalized => this * Mathf.InverseSqrt(u * u + i * i + j * j + k * k);
|
public Quaternion Normalized => this * Mathf.InverseSqrt(u * u + i * i + j * j + k * k);
|
||||||
|
|
||||||
public Float3 IJK => new(i, j, k);
|
public Float3 IJK
|
||||||
|
{
|
||||||
|
get => new(i, j, k);
|
||||||
|
set
|
||||||
|
{
|
||||||
|
i = value.x;
|
||||||
|
j = value.y;
|
||||||
|
k = value.z;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public float u, i, j, k;
|
public float u, i, j, k;
|
||||||
|
|
||||||
@ -136,27 +145,31 @@ public struct Quaternion : ICloneable, IComparable<Quaternion>, IEquatable<Quate
|
|||||||
return Float4.Sum(floats.ToArray());
|
return Float4.Sum(floats.ToArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Obsolete("This method does not produce the correct output. Please update to a newer release.")]
|
|
||||||
public static Quaternion FromAngles(Angle yaw, Angle pitch, Angle? roll = null)
|
public static Quaternion FromAngles(Angle yaw, Angle pitch, Angle? roll = null)
|
||||||
{
|
{
|
||||||
roll ??= Angle.Zero;
|
roll ??= Angle.Zero;
|
||||||
float cosYaw = Mathf.Cos(yaw), cosPitch = Mathf.Cos(pitch), cosRoll = Mathf.Cos(roll.Value),
|
float cosYaw, cosPitch, cosRoll, sinYaw, sinPitch, sinRoll,
|
||||||
sinYaw = Mathf.Sin(yaw), sinPitch = Mathf.Sin(pitch), sinRoll = Mathf.Sin(roll.Value);
|
cosYawCosPitch, sinYawSinPitch, cosYawSinPitch, sinYawCosPitch;
|
||||||
|
|
||||||
float cosYawCosPitch = cosYaw * cosPitch,
|
cosYaw = Mathf.Cos(yaw * 0.5f);
|
||||||
cosYawSinPitch = cosYaw * sinPitch,
|
cosPitch = Mathf.Cos(pitch * 0.5f);
|
||||||
sinYawCosPitch = sinYaw * cosPitch,
|
cosRoll = Mathf.Cos(roll.Value * 0.5f);
|
||||||
sinYawSinPitch = sinYaw * sinPitch;
|
sinYaw = Mathf.Sin(yaw * 0.5f);
|
||||||
|
sinPitch = Mathf.Sin(pitch * 0.5f);
|
||||||
|
sinRoll = Mathf.Sin(roll.Value * 0.5f);
|
||||||
|
|
||||||
|
cosYawCosPitch = cosYaw * cosPitch;
|
||||||
|
sinYawSinPitch = sinYaw * sinPitch;
|
||||||
|
cosYawSinPitch = cosYaw * sinPitch;
|
||||||
|
sinYawCosPitch = sinYaw * cosPitch;
|
||||||
|
|
||||||
return new(cosYawCosPitch * cosRoll + sinYawSinPitch * sinRoll,
|
return new(cosYawCosPitch * cosRoll + sinYawSinPitch * sinRoll,
|
||||||
cosYawCosPitch * sinRoll + sinYawSinPitch * cosRoll,
|
cosYawCosPitch * sinRoll - sinYawSinPitch * cosRoll,
|
||||||
cosYawSinPitch * cosRoll + sinYawCosPitch * sinRoll,
|
cosYawSinPitch * cosRoll + sinYawCosPitch * sinRoll,
|
||||||
sinYawCosPitch * cosRoll + cosYawSinPitch * sinRoll);
|
sinYawCosPitch * cosRoll - cosYawSinPitch * sinRoll);
|
||||||
}
|
}
|
||||||
[Obsolete("This method does not produce the correct output. Please update to a newer release.")]
|
|
||||||
public static Quaternion FromAngles(Float3 vals, Angle.Type valType) =>
|
public static Quaternion FromAngles(Float3 vals, Angle.Type valType) =>
|
||||||
FromAngles(new(vals.x, valType), new(vals.y, valType), new(vals.z, valType));
|
FromAngles(new(vals.x, valType), new(vals.y, valType), new(vals.z, valType));
|
||||||
[Obsolete("This method does not produce the correct output. Please update to a newer release.")]
|
|
||||||
public static Quaternion FromVector(Vector3d vec) => FromAngles(vec.yaw, vec.pitch);
|
public static Quaternion FromVector(Vector3d vec) => FromAngles(vec.yaw, vec.pitch);
|
||||||
|
|
||||||
public static (float[] Us, float[] Is, float[] Js, float[] Ks) SplitArray(params Quaternion[] vals)
|
public static (float[] Us, float[] Is, float[] Js, float[] Ks) SplitArray(params Quaternion[] vals)
|
||||||
@ -193,18 +206,8 @@ public struct Quaternion : ICloneable, IComparable<Quaternion>, IEquatable<Quate
|
|||||||
|
|
||||||
public object Clone() => new Quaternion(u, i, j, k);
|
public object Clone() => new Quaternion(u, i, j, k);
|
||||||
|
|
||||||
[Obsolete("This method does not produce the correct output. Please update to a newer release.")]
|
|
||||||
public Angle GetAngle() => Mathf.ArcCos(u) * 2;
|
public Angle GetAngle() => Mathf.ArcCos(u) * 2;
|
||||||
[Obsolete("This method does not produce the correct output. Please update to a newer release.")]
|
public Float3 GetAxis() => IJK.Normalized;
|
||||||
public Float3 GetAxis()
|
|
||||||
{
|
|
||||||
Float3 axis = IJK;
|
|
||||||
float mag = Magnitude;
|
|
||||||
|
|
||||||
if (mag < 0) return Float3.Zero;
|
|
||||||
return axis / mag;
|
|
||||||
}
|
|
||||||
[Obsolete("This method does not produce the correct output. Please update to a newer release.")]
|
|
||||||
public (Angle yaw, Angle pitch, Angle roll) ToAngles()
|
public (Angle yaw, Angle pitch, Angle roll) ToAngles()
|
||||||
{
|
{
|
||||||
Quaternion doubled = this;
|
Quaternion doubled = this;
|
||||||
@ -213,42 +216,47 @@ public struct Quaternion : ICloneable, IComparable<Quaternion>, IEquatable<Quate
|
|||||||
doubled.j *= j;
|
doubled.j *= j;
|
||||||
doubled.k *= k;
|
doubled.k *= k;
|
||||||
|
|
||||||
Matrix3x3 rotMatrix = new(new[,]
|
Matrix3x3 rot = new(new[,]
|
||||||
{
|
{
|
||||||
{ doubled.u + doubled.i - doubled.j - doubled.k, 0, 0 },
|
{ u * u + i * i - j * j - k * k, 2 * i * j + 2 * k * u, 2 * i * k - 2 * j * u },
|
||||||
{ 2 * (i * j + u * k), 0, 0 },
|
{ 2 * i * j - 2 * k * u, u * u - i * i + j * j - k * k, 2 * j * k + 2 * i * u },
|
||||||
{ 2 * (i * k + u * j), 2 * (j * k + u * i), doubled.u - doubled.i - doubled.j + doubled.k }
|
{ 2 * k * i + 2 * j * u, 2 * k * j - 2 * i * u, u * u - i * i - j * j + k * k }
|
||||||
});
|
});
|
||||||
|
|
||||||
Angle yaw, pitch, roll;
|
Angle yaw, pitch, roll;
|
||||||
|
|
||||||
float r3c1Abs = Mathf.Absolute(rotMatrix.r3c1);
|
float absr3c1 = Mathf.Absolute(rot.r3c1);
|
||||||
if (r3c1Abs >= 1)
|
if (absr3c1 >= 1)
|
||||||
{
|
{
|
||||||
rotMatrix.r1c2 = 2 * (i * j - u * k);
|
yaw = Mathf.ArcTan2(-rot.r1c2, -rot.r3c1 * rot.r1c3);
|
||||||
rotMatrix.r1c3 = 2 * (i * k + u * j);
|
pitch = new(-Constants.HalfPi * rot.r3c1 / absr3c1, Angle.Type.Radians);
|
||||||
|
|
||||||
yaw = Mathf.ArcTan2(-rotMatrix.r1c2, -rotMatrix.r3c1 * rotMatrix.r1c3);
|
|
||||||
pitch = new(-Constants.HalfPi * rotMatrix.r3c1 / r3c1Abs, Angle.Type.Radians);
|
|
||||||
roll = Angle.Zero;
|
roll = Angle.Zero;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
yaw = Mathf.ArcTan2(rotMatrix.r2c1, rotMatrix.r1c1);
|
yaw = Mathf.ArcTan2(rot.r2c1, rot.r1c1);
|
||||||
pitch = Mathf.ArcSin(-rotMatrix.r3c1);
|
pitch = Mathf.ArcSin(-rot.r3c1);
|
||||||
roll = Mathf.ArcTan2(rotMatrix.r3c2, rotMatrix.r3c3);
|
roll = Mathf.ArcTan2(rot.r3c2, rot.r3c3);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (yaw, pitch, roll);
|
return (yaw, pitch, roll);
|
||||||
}
|
}
|
||||||
[Obsolete("This method does not produce the correct output. Please update to a newer release.")]
|
public Float3 ToAnglesFloat3(Angle.Type type = Angle.Type.Degrees)
|
||||||
public Vector3d ToVector()
|
|
||||||
{
|
{
|
||||||
(Angle yaw, Angle pitch, _) = ToAngles();
|
(Angle yaw, Angle pitch, Angle roll) = ToAngles();
|
||||||
return new(yaw, pitch);
|
return new(yaw.ValueFromType(type), pitch.ValueFromType(type), roll.ValueFromType(type));
|
||||||
}
|
}
|
||||||
|
|
||||||
public Quaternion Rotate(Quaternion other) => other * this * other.Conjugate;
|
public Quaternion Rotate(Quaternion other) => this * other * Conjugate;
|
||||||
|
public Float3 Rotate(Float3 other)
|
||||||
|
{
|
||||||
|
const float tolerance = 0.001f;
|
||||||
|
Quaternion res = this * other * Conjugate;
|
||||||
|
if (Mathf.Absolute(res.u) > tolerance)
|
||||||
|
throw new MathException("A rotated vector should never have non-zero scalar part.");
|
||||||
|
return res.IJK;
|
||||||
|
}
|
||||||
|
public Vector3d Rotate(Vector3d other) => Rotate(other.ToXYZ()).ToVector();
|
||||||
|
|
||||||
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
||||||
public IEnumerator<float> GetEnumerator()
|
public IEnumerator<float> GetEnumerator()
|
||||||
@ -275,7 +283,7 @@ public struct Quaternion : ICloneable, IComparable<Quaternion>, IEquatable<Quate
|
|||||||
float a = x.u, b = x.i, c = x.j, d = x.k, e = y.u, f = y.i, g = y.j, h = y.k,
|
float a = x.u, b = x.i, c = x.j, d = x.k, e = y.u, f = y.i, g = y.j, h = y.k,
|
||||||
u = a * e - b * f - c * g - d * h,
|
u = a * e - b * f - c * g - d * h,
|
||||||
i = a * f + b * e + c * h - d * g,
|
i = a * f + b * e + c * h - d * g,
|
||||||
j = a * g + c * e + b * h - d * f,
|
j = a * g - b * h + c * e + d * f,
|
||||||
k = a * h + b * g + d * e - c * f;
|
k = a * h + b * g + d * e - c * f;
|
||||||
return new(u, i, j, k);
|
return new(u, i, j, k);
|
||||||
}
|
}
|
||||||
@ -286,6 +294,7 @@ public struct Quaternion : ICloneable, IComparable<Quaternion>, IEquatable<Quate
|
|||||||
public static Quaternion operator /(Quaternion a, float b) => new(a.u / b, a.i / b, a.j / b, a.k / b);
|
public static Quaternion operator /(Quaternion a, float b) => new(a.u / b, a.i / b, a.j / b, a.k / b);
|
||||||
public static Quaternion operator /(Quaternion a, Matrix b) => (Quaternion)((Matrix)a / b);
|
public static Quaternion operator /(Quaternion a, Matrix b) => (Quaternion)((Matrix)a / b);
|
||||||
public static Quaternion operator /(Quaternion a, Float3 b) => a / new Quaternion(b);
|
public static Quaternion operator /(Quaternion a, Float3 b) => a / new Quaternion(b);
|
||||||
|
public static Quaternion operator ~(Quaternion v) => v.Conjugate;
|
||||||
public static bool operator ==(Quaternion a, Quaternion b) => a.Equals(b);
|
public static bool operator ==(Quaternion a, Quaternion b) => a.Equals(b);
|
||||||
public static bool operator !=(Quaternion a, Quaternion b) => !a.Equals(b);
|
public static bool operator !=(Quaternion a, Quaternion b) => !a.Equals(b);
|
||||||
public static bool operator >(Quaternion a, Quaternion b) => a.CompareTo(b) > 0;
|
public static bool operator >(Quaternion a, Quaternion b) => a.CompareTo(b) > 0;
|
||||||
|
|||||||
46
Nerd_STF/Nerd_STF.csproj
Normal file
46
Nerd_STF/Nerd_STF.csproj
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<RootNamespace>Nerd_STF</RootNamespace>
|
||||||
|
<AssemblyName>Nerd_STF</AssemblyName>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<Authors>That_One_Nerd</Authors>
|
||||||
|
<Description>Nerd_STF is a C# library that runs on .Net 6.0, and contains added structures and classes I feel would help the default C# library package.</Description>
|
||||||
|
<Copyright>Copyright (c) 2022 That_One_Nerd</Copyright>
|
||||||
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
|
<RepositoryUrl>https://github.com/That-One-Nerd/Nerd_STF</RepositoryUrl>
|
||||||
|
<AssemblyVersion>2.3.1.52</AssemblyVersion>
|
||||||
|
<PackageTags>c#;csharp;c sharp;math;mathematics;mathametics;maths;color;rgb;rgba;cmyk;cmyka;hsv;hsva;calculus;linear algebra;linalg;linearalgebra;matrix;matrix2x2;matrix 2x2;matrix3x3;matrix 3x3;matrix4x4;matrix 4x4;matrix multiplication;vector;vector2d;vector3d;vector2;vector3;float2;float3;float4;int2;int3;int4;angle;geometry;vert;line;polygon;triangle;quadrilateral;sphere;circle;number system;numbersystem;complex numbers;complex;2d numbers;2dnumbers;quaternions;4d numbers;4dnumbers</PackageTags>
|
||||||
|
<Version>2.3.1.52-alpha</Version>
|
||||||
|
<Product>Nerd_STF</Product>
|
||||||
|
<PackageId>Nerd_STF</PackageId>
|
||||||
|
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||||
|
<PackageIcon>Logo Square0001.png</PackageIcon>
|
||||||
|
<PackageReleaseNotes>The `v2.3.1.x` updates go through every single field and method in Nerd_STF to make sure it works correctly.</PackageReleaseNotes>
|
||||||
|
<PackageProjectUrl>https://github.com/That-One-Nerd/Nerd_STF</PackageProjectUrl>
|
||||||
|
<GenerateDocumentationFile>False</GenerateDocumentationFile>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||||
|
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
||||||
|
<TreatWarningsAsErrors>True</TreatWarningsAsErrors>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="..\README.md">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
<None Include="..\..\..\Nerd_STF\Icons\Logo Square0001.png">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
36
Nerd_STF/Nerd_STF.sln
Normal file
36
Nerd_STF/Nerd_STF.sln
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.0.31903.59
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Nerd_STF", "Nerd_STF.csproj", "{1F2C87DB-56F2-48B7-8FF6-A12D8E3614DB}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Testing", "..\Testing\Testing.csproj", "{53E8335D-AE54-4E34-A692-136786788DD6}"
|
||||||
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{FBAFC98C-AC9E-4E76-A6E7-8F4DB1B23BED}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
.editorconfig = .editorconfig
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{1F2C87DB-56F2-48B7-8FF6-A12D8E3614DB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{1F2C87DB-56F2-48B7-8FF6-A12D8E3614DB}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{1F2C87DB-56F2-48B7-8FF6-A12D8E3614DB}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{1F2C87DB-56F2-48B7-8FF6-A12D8E3614DB}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{53E8335D-AE54-4E34-A692-136786788DD6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{53E8335D-AE54-4E34-A692-136786788DD6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{53E8335D-AE54-4E34-A692-136786788DD6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{53E8335D-AE54-4E34-A692-136786788DD6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {81A13C28-98B5-49F8-9141-C4A62EE8729F}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
8
Nerd_STF/ScaleType.cs
Normal file
8
Nerd_STF/ScaleType.cs
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
namespace Nerd_STF;
|
||||||
|
|
||||||
|
public enum ScaleType
|
||||||
|
{
|
||||||
|
X = 1,
|
||||||
|
Y = 2,
|
||||||
|
Both = X | Y
|
||||||
|
}
|
||||||
Binary file not shown.
Loading…
x
Reference in New Issue
Block a user