2using System.Collections;
3using System.Collections.Generic;
6using System.Threading.Tasks;
29 private readonly LinkedList<IMatrix> x =
new LinkedList<IMatrix>();
30 private readonly LinkedList<IMatrix> y =
new LinkedList<IMatrix>();
31 private readonly LinkedList<IMatrix> z =
new LinkedList<IMatrix>();
32 private readonly LinkedList<Vector4[,]> normals =
new LinkedList<Vector4[,]>();
33 private readonly LinkedList<object[]> parameters =
new LinkedList<object[]>();
34 private readonly LinkedList<IPainter3D> painters =
new LinkedList<IPainter3D>();
38 private Type axisTypeX;
39 private Type axisTypeY;
40 private Type axisTypeZ;
41 private string title =
string.Empty;
42 private string labelX =
string.Empty;
43 private string labelY =
string.Empty;
44 private string labelZ =
string.Empty;
45 private double angle = 20;
46 private double inclination = 30;
47 private int overSampling = 2;
48 private bool showXAxis =
true;
49 private bool showYAxis =
true;
50 private bool showZAxis =
true;
51 private bool showGrid =
true;
72 : base(
Variables, DefaultWidth, DefaultHeight)
107 if (c !=
Y.Columns || d !=
Y.Rows || c !=
Z.Columns || d !=
Z.Rows)
108 throw new ScriptException(
"X, Y and Z matrices must be of equal dimensions.");
111 throw new ScriptException(
"Normal matrix must be of equal dimensions as axes.");
122 Zero = AG.AdditiveIdentity;
133 Zero = AG2.AdditiveIdentity;
144 Zero = AG3.AdditiveIdentity;
150 this.axisTypeX =
X.GetType();
151 this.axisTypeY =
Y.GetType();
152 this.axisTypeZ =
Z.GetType();
160 this.painters.AddLast(Painter);
168 public LinkedList<IMatrix>
X => this.x;
173 public LinkedList<IMatrix>
Y => this.y;
178 public LinkedList<IMatrix>
Z => this.z;
183 public LinkedList<Vector4[,]>
Normals => this.normals;
226 set => this.title = value;
235 set => this.labelX = value;
244 set => this.labelY = value;
253 set => this.labelZ = value;
261 get => this.showXAxis;
262 set => this.showXAxis = value;
270 get => this.showYAxis;
271 set => this.showYAxis = value;
279 get => this.showZAxis;
280 set => this.showZAxis = value;
288 get => this.showGrid;
289 set => this.showGrid = value;
298 set => this.angle = value;
306 get => this.inclination;
307 set => this.inclination = value;
315 get => this.overSampling;
319 throw new ArgumentException(
"Must be a positive integer.", nameof(this.
Oversampling));
321 this.overSampling = value;
342 return this.
AddRight(Element,
false);
352 return Element.AddRightElementWise(
this);
373 if (this.x.First is
null)
379 if (G.x.First is
null)
384 axisTypeX = this.axisTypeX,
385 axisTypeY = this.axisTypeY,
386 axisTypeZ = this.axisTypeZ,
388 labelX = this.labelX,
389 labelY = this.labelY,
390 labelZ = this.labelZ,
403 foreach (Vector4[,] M
in this.normals)
404 Result.normals.AddLast(M);
407 Result.painters.AddLast(Painter);
409 foreach (
object[] P
in this.parameters)
410 Result.parameters.AddLast(P);
414 if (M.GetType() !=
this.axisTypeX)
422 if (M.GetType() !=
this.axisTypeY)
430 if (M.GetType() !=
this.axisTypeZ)
436 foreach (Vector4[,] M
in G.normals)
437 Result.normals.AddLast(M);
440 Result.painters.AddLast(Painter);
442 foreach (
object[] P
in G.parameters)
443 Result.parameters.AddLast(P);
452 Result.showXAxis |= G.showXAxis;
453 Result.showYAxis |= G.showYAxis;
454 Result.showZAxis |= G.showZAxis;
466 this.minX.Equals(G.minX) &&
467 this.maxX.Equals(G.maxX) &&
468 this.minY.Equals(G.minY) &&
469 this.maxY.Equals(G.maxY) &&
470 this.minZ.Equals(G.minZ) &&
471 this.maxZ.Equals(G.maxZ) &&
472 this.axisTypeX.Equals(G.axisTypeX) &&
473 this.axisTypeY.Equals(G.axisTypeY) &&
474 this.axisTypeZ.Equals(G.axisTypeZ) &&
475 this.title.Equals(G.title) &&
476 this.labelX.Equals(G.labelX) &&
477 this.labelY.Equals(G.labelY) &&
478 this.labelZ.Equals(G.labelZ) &&
479 this.showXAxis.Equals(G.showXAxis) &&
480 this.showYAxis.Equals(G.showYAxis) &&
481 this.showZAxis.Equals(G.showZAxis) &&
482 this.showGrid.Equals(G.showGrid) &&
483 this.Equals(
this.x.GetEnumerator(), G.x.GetEnumerator()) &&
484 this.Equals(
this.y.GetEnumerator(), G.y.GetEnumerator()) &&
485 this.Equals(
this.z.GetEnumerator(), G.z.GetEnumerator()) &&
486 this.Equals(
this.normals?.GetEnumerator(), G.normals?.GetEnumerator()) &&
487 this.Equals(
this.parameters.GetEnumerator(), G.parameters.GetEnumerator()) &&
488 this.Equals(
this.painters.GetEnumerator(), G.painters.GetEnumerator()));
491 private bool Equals(IEnumerator e1, IEnumerator e2)
493 if ((e1 is
null) ^ (e2 is
null))
499 bool b1 = e1.MoveNext();
500 bool b2 = e2.MoveNext();
504 if (!e1.Current.Equals(e2.Current))
517 int Result = this.minX.GetHashCode();
518 Result ^= Result << 5 ^ this.maxX.GetHashCode();
519 Result ^= Result << 5 ^ this.minY.GetHashCode();
520 Result ^= Result << 5 ^ this.maxY.GetHashCode();
521 Result ^= Result << 5 ^ this.minZ.GetHashCode();
522 Result ^= Result << 5 ^ this.maxZ.GetHashCode();
523 Result ^= Result << 5 ^ this.axisTypeX.GetHashCode();
524 Result ^= Result << 5 ^ this.axisTypeY.GetHashCode();
525 Result ^= Result << 5 ^ this.axisTypeZ.GetHashCode();
526 Result ^= Result << 5 ^ this.title.GetHashCode();
527 Result ^= Result << 5 ^ this.labelX.GetHashCode();
528 Result ^= Result << 5 ^ this.labelY.GetHashCode();
529 Result ^= Result << 5 ^ this.labelZ.GetHashCode();
530 Result ^= Result << 5 ^ this.showXAxis.GetHashCode();
531 Result ^= Result << 5 ^ this.showYAxis.GetHashCode();
532 Result ^= Result << 5 ^ this.showZAxis.GetHashCode();
533 Result ^= Result << 5 ^ this.showGrid.GetHashCode();
536 Result ^= Result << 5 ^ E.GetHashCode();
539 Result ^= Result << 5 ^ E.GetHashCode();
542 Result ^= Result << 5 ^ E.GetHashCode();
544 if (!(this.normals is
null))
546 foreach (Vector4[,]
Normals in this.normals)
547 Result ^= Result << 5 ^
Normals.GetHashCode();
550 foreach (
object Obj
in this.parameters)
551 Result ^= Result << 5 ^ Obj.GetHashCode();
554 Result ^= Result << 5 ^ Painter.GetHashCode();
583 this.minX.AssociatedObjectValue is
double MinX &&
593 double SX = Width / (DX == 0 ? 1 : DX);
594 double SY = Height / (DY == 0 ? 1 : DY);
595 double SZ = Depth / (DZ == 0 ? 1 : DZ);
596 double MinScale = Math.Min(SX, Math.Min(SY, SZ));
600 int Height2 = (int)(Height * SX / SY + 0.5);
601 OffsetY += (Height - Height2) / 2;
604 int Depth2 = (int)(Depth * SX / SZ + 0.5);
605 OffsetZ += (Depth - Depth2) / 2;
608 else if (SY == MinScale)
610 int Width2 = (int)(Width * SY / SX + 0.5);
611 OffsetX += (Width - Width2) / 2;
614 int Depth2 = (int)(Depth * SY / SZ + 0.5);
615 OffsetZ += (Depth - Depth2) / 2;
620 int Width2 = (int)(Width * SZ / SX + 0.5);
621 OffsetX += (Width - Width2) / 2;
624 int Height2 = (int)(Height * SZ / SY + 0.5);
625 OffsetY += (Height - Height2) / 2;
631 OrigoX = (float)
Scale(
new ObjectVector(AgX.AdditiveIdentity), this.minX, this.maxX, OffsetX, Width,
null)[0];
636 OrigoY = (float)
Scale(
new ObjectVector(AgY.AdditiveIdentity), this.minY, this.maxY, OffsetY, Height,
null)[0];
641 OrigoZ = (float)
Scale(
new ObjectVector(AgZ.AdditiveIdentity), this.maxZ, this.minZ, OffsetZ, Depth,
null)[0];
645 float PlaneX = OrigoX ?? OffsetX;
646 float PlaneY = OrigoY ?? OffsetY;
647 float PlaneZ = OrigoZ ?? OffsetZ + Depth;
650 this.minY, this.maxY, this.minZ, this.maxZ, OffsetX, OffsetY, OffsetZ,
651 Width, Height, Depth, OrigoX, OrigoY, OrigoZ);
653 Dictionary<string, double> XLabelPositions = XLabelType == LabelType.String ?
new Dictionary<string, double>() :
null;
654 Dictionary<string, double> YLabelPositions = YLabelType == LabelType.String ?
new Dictionary<string, double>() :
null;
655 Dictionary<string, double> ZLabelPositions = ZLabelType == LabelType.String ?
new Dictionary<string, double>() :
null;
659 string[] XLabelStrings =
LabelStrings(XLabels, XLabelType);
660 string[] YLabelStrings =
LabelStrings(YLabels, YLabelType);
661 string[] ZLabelStrings =
LabelStrings(ZLabels, ZLabelType);
665 if (!(XLabelPositions is
null))
671 s = XLabelStrings[i];
672 XLabelPositions[s] = LabelXX[i++];
676 if (!(YLabelPositions is
null))
682 s = YLabelStrings[i];
683 YLabelPositions[s] = LabelYY[i++];
687 if (!(ZLabelPositions is
null))
693 s = ZLabelStrings[i];
694 ZLabelPositions[s] = LabelZZ[i++];
698 DrawingVolume.XLabelPositions = XLabelPositions;
699 DrawingVolume.YLabelPositions = YLabelPositions;
700 DrawingVolume.ZLabelPositions = ZLabelPositions;
705 Canvas.
RotateX(-(
float)this.inclination,
new Vector3(0, 0, 1500));
706 Canvas.
RotateY((
float)this.angle,
new Vector3(0, 0, 1500));
708 IEnumerator<IMatrix> ex = this.x.GetEnumerator();
709 IEnumerator<IMatrix> ey = this.y.GetEnumerator();
710 IEnumerator<IMatrix> ez = this.z.GetEnumerator();
711 IEnumerator<Vector4[,]> eN = this.normals.GetEnumerator();
712 IEnumerator<object[]> eParameters = this.parameters.GetEnumerator();
713 IEnumerator<IPainter3D> ePainters = this.painters.GetEnumerator();
716 Vector4[,] PrevPoints =
null;
717 Vector4[,] PrevNormals =
null;
718 object[] PrevParameters =
null;
721 while (ex.MoveNext() && ey.MoveNext() && ez.MoveNext() &&
722 eN.MoveNext() && eParameters.MoveNext() && ePainters.MoveNext())
727 if (!(PrevPainter is
null) && ePainters.Current.GetType() == PrevPainter.GetType())
728 ePainters.Current.DrawGraph(Canvas, Points,
Normals, eParameters.Current, PrevPoints, PrevNormals, PrevParameters,
DrawingVolume);
730 ePainters.Current.DrawGraph(Canvas, Points,
Normals, eParameters.Current,
null,
null,
null,
DrawingVolume);
734 PrevParameters = eParameters.Current;
735 PrevPainter = ePainters.Current;
740 float TextSize0 = (
float)Settings.LabelFontSize * 5;
741 float TextSize = this.CalcTextSize(LabelXX, TextSize0);
749 s = XLabelStrings[i];
752 f = (float)LabelXX[i++];
758 this.DrawPlaneLine(Canvas,
759 new Vector4(f, PlaneY, OffsetZ, 1),
760 new Vector4(f, PlaneY, OffsetZ + Depth, 1),
763 this.DrawPlaneLine(Canvas,
764 new Vector4(f, OffsetY, PlaneZ, 1),
765 new Vector4(f, OffsetY + Height, PlaneZ, 1),
770 this.DrawPlaneLine(Canvas,
771 new Vector4(f, PlaneY, OffsetZ, 1),
772 new Vector4(f, PlaneY, OffsetZ + Depth, 1),
775 this.DrawPlaneLine(Canvas,
776 new Vector4(f, OffsetY, PlaneZ, 1),
777 new Vector4(f, OffsetY + Height, PlaneZ, 1),
784 Canvas.Translate(f, PlaneY, OffsetZ);
788 new Vector4(-5 * LabelMargin - Size.Width, LabelMargin - Size.Height / 2, 0, 1),
790 Canvas.ModelTransformation = M;
794 if (!
string.IsNullOrEmpty(this.labelX))
796 Size = Canvas.TextDimensions(this.labelX,
Settings.
FontName, TextSize0 * 1.25f);
798 Canvas.Translate(OffsetX + Width / 2, PlaneY, OffsetZ);
800 Canvas.Text(this.labelX,
801 new Vector4(-Size.Width / 2, -2 * Size.Height, 0, 1),
803 Canvas.ModelTransformation = M;
807 TextSize = this.CalcTextSize(LabelZZ, TextSize0);
811 s = ZLabelStrings[i];
814 f = (float)LabelZZ[i++];
820 this.DrawPlaneLine(Canvas,
821 new Vector4(OffsetX, PlaneY, f, 1),
822 new Vector4(OffsetX + Width, PlaneY, f, 1),
825 this.DrawPlaneLine(Canvas,
826 new Vector4(PlaneX, OffsetY, f, 1),
827 new Vector4(PlaneX, OffsetY + Height, f, 1),
832 this.DrawPlaneLine(Canvas,
833 new Vector4(OffsetX, PlaneY, f, 1),
834 new Vector4(OffsetX + Width, PlaneY, f, 1),
837 this.DrawPlaneLine(Canvas,
838 new Vector4(PlaneX, OffsetY, f, 1),
839 new Vector4(PlaneX, OffsetY + Height, f, 1),
846 Canvas.Translate(OffsetX + Width, PlaneY, f);
849 new Vector4(5 * LabelMargin, LabelMargin - Size.Height / 2, 0, 1),
851 Canvas.ModelTransformation = M;
855 if (!
string.IsNullOrEmpty(this.labelZ))
857 Size = Canvas.TextDimensions(this.labelZ,
Settings.
FontName, TextSize0 * 1.25f);
859 Canvas.Translate(OffsetX + Width, PlaneY, OffsetZ + Depth / 2);
862 Canvas.Text(this.labelZ,
863 new Vector4(-Size.Width / 2, -2 * Size.Height, 0, 1),
865 Canvas.ModelTransformation = M;
869 TextSize = this.CalcTextSize(LabelYY, TextSize0);
873 s = YLabelStrings[i];
876 f = (float)LabelYY[i++];
882 this.DrawPlaneLine(Canvas,
883 new Vector4(PlaneX, f, OffsetZ, 1),
884 new Vector4(PlaneX, f, OffsetZ + Depth, 1),
887 this.DrawPlaneLine(Canvas,
888 new Vector4(OffsetX, f, PlaneZ, 1),
889 new Vector4(OffsetX + Width, f, PlaneZ, 1),
894 this.DrawPlaneLine(Canvas,
895 new Vector4(PlaneX, f, OffsetZ, 1),
896 new Vector4(PlaneX, f, OffsetZ + Depth, 1),
899 this.DrawPlaneLine(Canvas,
900 new Vector4(OffsetX, f, PlaneZ, 1),
901 new Vector4(OffsetX + Width, f, PlaneZ, 1),
908 Canvas.Translate(OffsetX, f, PlaneZ);
910 new Vector4(-5 * LabelMargin - Size.Width, LabelMargin - Size.Height / 2, 0, 1),
912 Canvas.ModelTransformation = M;
916 if (!
string.IsNullOrEmpty(this.labelY))
918 Size = Canvas.TextDimensions(this.labelY,
Settings.
FontName, TextSize0 * 1.25f);
920 Canvas.Translate(OffsetX, OffsetY + Height / 2, PlaneZ);
922 Canvas.Text(this.labelY,
923 new Vector4(-Size.Width / 2, 2 * Size.Height, 0, 1),
925 Canvas.ModelTransformation = M;
928 if (!
string.IsNullOrEmpty(this.title))
930 Size = Canvas.TextDimensions(this.title,
Settings.
FontName, TextSize0 * 1.5f);
932 Canvas.Translate(OffsetX + Width / 2, OffsetY + Height, OffsetZ + Depth / 2);
933 Canvas.Text(this.title,
934 new Vector4(-Size.Width / 2, Size.Height / 2, 0, 1),
936 Canvas.ModelTransformation = M;
942 this.DrawPlane(Canvas,
943 new Vector4(OffsetX, OffsetY, PlaneZ, 1),
944 new Vector4(OffsetX + Width, OffsetY, PlaneZ, 1),
945 new Vector4(OffsetX + Width, OffsetY + Height, PlaneZ, 1),
946 new Vector4(OffsetX, OffsetY + Height, PlaneZ, 1),
947 AxisPlaneShader,
true, 3);
949 this.DrawPlane(Canvas,
950 new Vector4(OffsetX, PlaneY, OffsetZ, 1),
951 new Vector4(OffsetX + Width, PlaneY, OffsetZ, 1),
952 new Vector4(OffsetX + Width, PlaneY, OffsetZ + Depth, 1),
953 new Vector4(OffsetX, PlaneY, OffsetZ + Depth, 1),
954 AxisPlaneShader,
true, 3);
956 this.DrawPlane(Canvas,
957 new Vector4(PlaneX, OffsetY, OffsetZ, 1),
958 new Vector4(PlaneX, OffsetY, OffsetZ + Depth, 1),
959 new Vector4(PlaneX, OffsetY + Height, OffsetZ + Depth, 1),
960 new Vector4(PlaneX, OffsetY + Height, OffsetZ, 1),
961 AxisPlaneShader,
true, 3);
963 return Canvas.CreatePixels(
Settings, out States);
966 private float CalcTextSize(
double[] LabelPositions,
float TextSize)
968 int i, c = LabelPositions.Length;
971 for (i = 1; i < c; i++)
973 Diff = (float)(Math.Abs(LabelPositions[i] - LabelPositions[i - 1]));
981 private void DrawPlaneLine(Canvas3D Canvas, Vector4 P0, Vector4 P1,
982 SKColor Color,
int Halvings)
985 Canvas.Line(P0, P1, Color);
990 Vector4 Pm = (P0 + P1) / 2;
992 this.DrawPlaneLine(Canvas, P0, Pm, Color, Halvings);
993 this.DrawPlaneLine(Canvas, Pm, P1, Color, Halvings);
997 private void DrawPlane(Canvas3D Canvas, Vector4 P0, Vector4 P1, Vector4 P2, Vector4 P3,
998 I3DShader Shader,
bool TwoSided,
int Halvings)
1001 Canvas.Polygon(
new Vector4[] { P0, P1, P2, P3 }, Shader, TwoSided);
1006 Vector4 Pm = (P0 + P1 + P2 + P3) / 4;
1007 Vector4 P0p = (P3 + P0) / 2;
1008 Vector4 P1p = (P0 + P1) / 2;
1009 Vector4 P2p = (P1 + P2) / 2;
1010 Vector4 P3p = (P2 + P3) / 2;
1012 this.DrawPlane(Canvas, Pm, P2p, P2, P3p, Shader, TwoSided, Halvings);
1013 this.DrawPlane(Canvas, P1p, P1, P2p, Pm, Shader, TwoSided, Halvings);
1014 this.DrawPlane(Canvas, P3, P0p, Pm, P3p, Shader, TwoSided, Halvings);
1015 this.DrawPlane(Canvas, P0p, P0, P1p, Pm, Shader, TwoSided, Halvings);
1030 if (
Min.AssociatedObjectValue is
double DMin &&
1031 Max.AssociatedObjectValue is
double DMax)
1036 else if (
Min.AssociatedObjectValue is DateTime DTMin &&
1037 Max.AssociatedObjectValue is DateTime DTMax)
1045 return new ObjectVector(
GetLabels(PQMin.ToPhysicalQuantity(), PQMax.ToPhysicalQuantity(), ApproxNrLabels));
1047 else if (
Min.AssociatedObjectValue is
string &&
Max.AssociatedObjectValue is
string)
1049 Dictionary<string, bool> Indices =
new Dictionary<string, bool>();
1050 List<IElement> Labels =
new List<IElement>();
1053 foreach (
IMatrix Matrix
in Series)
1058 if (Indices.ContainsKey(s))
1068 if (Labels.Count > 0)
1071 Max = Labels[Labels.Count - 1];
1078 SortedDictionary<string, bool> Labels =
new SortedDictionary<string, bool>();
1080 foreach (
IMatrix Matrix
in Series)
1086 string[] Labels2 =
new string[Labels.Count];
1087 Labels.Keys.CopyTo(Labels2, 0);
1119 double Width,
double Height,
double Depth, Dictionary<string, double> XLabelPositions,
1120 Dictionary<string, double> YLabelPositions, Dictionary<string, double> ZLabelPositions)
1122 int Columns = MatrixX.
Columns;
1123 int Rows = MatrixX.
Rows;
1125 if (MatrixY.
Columns != Columns || MatrixY.
Rows != Rows ||
1126 MatrixZ.
Columns != Columns || MatrixZ.
Rows != Rows)
1131 double[,]
X =
Scale(MatrixX,
MinX,
MaxX, OffsetX, Width, XLabelPositions);
1132 double[,]
Y =
Scale(MatrixY,
MinY,
MaxY, OffsetY, Height, YLabelPositions);
1133 double[,]
Z =
Scale(MatrixZ,
MinZ,
MaxZ, OffsetZ, Depth, ZLabelPositions);
1135 Vector4[,] Points =
new Vector4[Columns, Rows];
1137 for (i = 0; i < Columns; i++)
1139 for (j = 0; j < Rows; j++)
1140 Points[i, j] =
new Vector4((
float)
X[i, j], (
float)
Y[i, j], (
float)
Z[i, j], 1);
1157 double Size, Dictionary<string, double> LabelPositions)
1161 if (!(
Min.AssociatedObjectValue is
double dMin) ||
1162 !(
Max.AssociatedObjectValue is
double dMax))
1167 return Scale(DM.Values, dMin, dMax, Offset, Size);
1194 for (i = 0; i < c; i++)
1196 for (j = 0; j < r; j++)
1208 if (
Min.AssociatedObjectValue is
double MinD &&
1209 Max.AssociatedObjectValue is
double MaxD)
1211 double[,] Matrix2 =
new double[c, r];
1214 for (i = 0; i < c; i++)
1216 for (j = 0; j < r; j++)
1220 Matrix2[i, j] = D.
Value;
1224 return Scale(Matrix2, MinD, MaxD, Offset, Size);
1228 if (
Min.AssociatedObjectValue is DateTime MinDT &&
1229 Max.AssociatedObjectValue is DateTime MaxDT)
1231 DateTime[,] Matrix2 =
new DateTime[c, r];
1234 for (i = 0; i < c; i++)
1236 for (j = 0; j < r; j++)
1240 Matrix2[i, j] = DT.
Value;
1244 return Scale(Matrix2, MinDT, MaxDT, Offset, Size);
1247 return Scale(OM.Values, Offset, Size, LabelPositions);
1264 public static double[,]
Scale(
double[,] Matrix,
double Min,
double Max,
double Offset,
double Size)
1266 int c = Matrix.GetLength(0);
1267 int r = Matrix.GetLength(1);
1269 double[,] Result =
new double[c, r];
1272 for (i = 0; i < c; i++)
1274 for (j = 0; j < r; j++)
1275 Result[i, j] = (Matrix[i, j] -
Min) *
Scale + Offset;
1290 public static double[,]
Scale(DateTime[,] Matrix, DateTime
Min, DateTime
Max,
double Offset,
double Size)
1292 int c = Matrix.GetLength(0);
1293 int r = Matrix.GetLength(1);
1295 double[,] v =
new double[c, r];
1297 for (i = 0; i < c; i++)
1299 for (j = 0; j < r; j++)
1318 int c = Matrix.GetLength(0);
1319 int r = Matrix.GetLength(1);
1321 double[,] v =
new double[c, r];
1324 for (i = 0; i < c; i++)
1326 for (j = 0; j < r; j++)
1347 public static double[,]
Scale(
object[,] Matrix,
double Offset,
double Size,
1348 Dictionary<string, double> LabelPositions)
1350 Dictionary<object, int> Values =
new Dictionary<object, int>();
1352 int c = Matrix.GetLength(0);
1353 int r = Matrix.GetLength(1);
1355 double[,] v =
new double[c, r];
1358 for (i = 0; i < c; i++)
1360 for (j = 0; j < r; j++)
1362 Value = Matrix[i, j];
1363 if (!Values.TryGetValue(Value, out
int k))
1373 double[,] Result =
Scale(v, 0, c, Offset, Size);
1375 if (!(LabelPositions is
null))
1377 for (i = 0; i < c; i++)
1379 for (j = 0; j < r; j++)
1381 string s = Matrix[i, j]?.ToString() ??
string.Empty;
1383 if (LabelPositions.TryGetValue(s, out
double d))
1406 return "[" + X2.ToString() +
"," + Y2.ToString() +
"]";
1419 if (!(Argument is SKColor Color))
1428 new PhongIntensity(Color.Red, Color.Green, Color.Blue, Color.Alpha),
1430 new Vector3(1000, 1000, 0)));
1439 Output.WriteStartElement(
"Graph3D");
1440 Output.WriteAttributeString(
"title", this.title);
1441 Output.WriteAttributeString(
"labelX", this.labelX);
1442 Output.WriteAttributeString(
"labelY", this.labelY);
1443 Output.WriteAttributeString(
"labelZ", this.labelZ);
1444 Output.WriteAttributeString(
"axisTypeX", this.axisTypeX.FullName);
1445 Output.WriteAttributeString(
"axisTypeY", this.axisTypeY.FullName);
1446 Output.WriteAttributeString(
"axisTypeZ", this.axisTypeZ.FullName);
1453 Output.WriteAttributeString(
"showXAxis", this.showXAxis ?
"true" :
"false");
1454 Output.WriteAttributeString(
"showYAxis", this.showYAxis ?
"true" :
"false");
1455 Output.WriteAttributeString(
"showZAxis", this.showZAxis ?
"true" :
"false");
1456 Output.WriteAttributeString(
"showGrid", this.showGrid ?
"true" :
"false");
1459 Output.WriteAttributeString(
"overSampling", this.overSampling.ToString());
1461 Dictionary<string, string> Series =
new Dictionary<string, string>();
1469 if (Series.TryGetValue(s, out Label))
1470 Output.WriteElementString(
"X", Label);
1473 Label =
"X" + (i++).ToString();
1475 Output.WriteElementString(
"X", Label +
":=" + s);
1484 if (Series.TryGetValue(s, out Label))
1485 Output.WriteElementString(
"Y", Label);
1488 Label =
"Y" + (i++).ToString();
1490 Output.WriteElementString(
"Y", Label +
":=" + s);
1499 if (Series.TryGetValue(s, out Label))
1500 Output.WriteElementString(
"Z", Label);
1503 Label =
"Z" + (i++).ToString();
1505 Output.WriteElementString(
"Z", Label +
":=" + s);
1511 foreach (Vector4[,] M
in this.normals)
1513 StringBuilder sb =
new StringBuilder();
1519 int c = M.GetLength(0);
1520 int d = M.GetLength(1);
1524 for (i = 0; i < c; i++)
1531 for (j = 0; j < d; j++)
1546 if (Series.TryGetValue(s, out Label))
1547 Output.WriteElementString(
"Normals", Label);
1550 Label =
"N" + (i++).ToString();
1552 Output.WriteElementString(
"Normals", Label +
":=" + s);
1558 foreach (
object[] v
in this.parameters)
1561 if (Series.TryGetValue(s, out Label))
1562 Output.WriteElementString(
"Parameters", Label);
1565 Label =
"P" + (i++).ToString();
1567 Output.WriteElementString(
"Parameters", Label +
":=" + s);
1571 foreach (
IPainter3D Painter
in this.painters)
1572 Output.WriteElementString(
"Painter", Painter.GetType().FullName);
1574 Output.WriteEndElement();
1585 foreach (XmlAttribute Attr
in Xml.Attributes)
1590 this.title = Attr.Value;
1594 this.labelX = Attr.Value;
1598 this.labelY = Attr.Value;
1602 this.labelZ = Attr.Value;
1642 this.showXAxis = Attr.Value ==
"true";
1646 this.showYAxis = Attr.Value ==
"true";
1650 this.showZAxis = Attr.Value ==
"true";
1654 this.showGrid = Attr.Value ==
"true";
1664 this.inclination = d;
1667 case "overSampling":
1668 this.overSampling =
int.Parse(Attr.Value);
1673 foreach (XmlNode N
in Xml.ChildNodes)
1675 if (N is XmlElement E)
1677 switch (E.LocalName)
1697 this.normals.AddLast((Vector4[,])
null);
1702 Vector4[,] M2 =
new Vector4[c, d];
1704 for (i = 0; i < c; i++)
1706 for (j = 0; i < d; j++)
1710 this.normals.AddLast(M2);
1734 IEnumerator<object[]> eParameters = this.parameters.GetEnumerator();
1735 IEnumerator<IPainter3D> ePainter = this.painters.GetEnumerator();
1737 while (eParameters.MoveNext() && ePainter.MoveNext())
1739 if (!ePainter.Current.UsesDefaultColor(eParameters.Current))
1757 IEnumerator<object[]> eParameters = this.parameters.GetEnumerator();
1758 IEnumerator<IPainter3D> ePainter = this.painters.GetEnumerator();
1761 while (eParameters.MoveNext() && ePainter.MoveNext())
1763 if (!ePainter.Current.TrySetDefaultColor(Color, eParameters.Current))
Static class that dynamically manages types and interfaces available in the runtime environment.
static Type GetType(string FullName)
Gets a type, given its full name.
Base class for all types of elements.
Element()
Base class for all types of elements.
Base class for script exceptions.
Class managing a script expression.
static bool TryParse(string s, out double Value)
Tries to parse a double-precision floating-point value.
static string ToString(double Value)
Converts a value to a string, that can be parsed as part of an expression.
static double CalcMax(double[] Values, ScriptNode Node)
Returns the largest value.
static double CalcMin(double[] Values, ScriptNode Node)
Returns the smallest value.
Matrix4x4 RotateY(float Degrees)
Rotates the world around the Y-axis.
Matrix4x4 Perspective(float NearPlaneDistance, float FarPlaneDistance)
Applies a perspective projection.
Matrix4x4 ModelTransformation
Current model transformation matrix.
Matrix4x4 RotateX(float Degrees)
Rotates the world around the X-axis.
Contains information about the current drawing area.
double[,] ScaleX(IMatrix Matrix)
Scales a matrix with x-coordinates to fit a given volume.
double[,] ScaleY(IMatrix Matrix)
Scales a matrix with y-coordinates to fit a given volume.
Vector4[,] Scale(IMatrix MatrixX, IMatrix MatrixY, IMatrix MatrixZ)
Scales three matrices of equal size to point vectors in space.
double[,] ScaleZ(IMatrix Matrix)
Scales a matrix with z-coordinates to fit a given volume.
Handles three-dimensional graphs.
double Inclination
Inclination, in degrees (rotation angle, around the X-axis).
override async Task ImportGraphAsync(XmlElement Xml)
Imports graph specifics from XML.
static double[,] Scale(IMatrix Matrix, IElement Min, IElement Max, double Offset, double Size, Dictionary< string, double > LabelPositions)
Scales a matrix to fit a given volume.
static double[,] Scale(object[,] Matrix, double Offset, double Size, Dictionary< string, double > LabelPositions)
Scales a matrix to fit a given volume.
Graph3D(Variables Variables, IMatrix X, IMatrix Y, IMatrix Z, Vector4[,] Normals, IPainter3D Painter, bool ShowZeroX, bool ShowZeroY, bool ShowZeroZ, ScriptNode Node, params object[] Parameters)
Base class for three-dimensional graphs.
static double[,] Scale(DateTime[,] Matrix, DateTime Min, DateTime Max, double Offset, double Size)
Scales a matrix to fit a given volume.
override int GetHashCode()
Calculates a hash code of the element. Hash code.
LinkedList< IMatrix > X
X-axis series.
override PixelInformation CreatePixels(GraphSettings Settings, out object[] States)
Creates a bitmap of the graph.
IElement MaxX
Largest X-value.
static double[,] Scale(PhysicalQuantity[,] Matrix, double Min, double Max, Unit Unit, double Offset, double Size)
Scales a matrix to fit a given volume.
IElement MinX
Smallest X-value.
IElement MaxZ
Largest Z-value.
override ISemiGroupElement AddLeft(ISemiGroupElement Element)
Tries to add an element to the current element, from the left.
static I3DShader ToShader(object Argument)
Gets a shader object from an argument.
override ISemiGroupElementWise AddLeftElementWise(ISemiGroupElementWise Element)
Tries to add an element to the current element, from the left, element-wise.
LinkedList< IMatrix > Z
Z-axis series.
override bool UsesDefaultColor
If graph uses default color
override bool Equals(object obj)
Compares the element to another. If elements are equal.
double Angle
Rotation angle, in degrees, around the Y-axis.
static Vector4[,] Scale(IMatrix MatrixX, IMatrix MatrixY, IMatrix MatrixZ, IElement MinX, IElement MaxX, IElement MinY, IElement MaxY, IElement MinZ, IElement MaxZ, double OffsetX, double OffsetY, double OffsetZ, double Width, double Height, double Depth, Dictionary< string, double > XLabelPositions, Dictionary< string, double > YLabelPositions, Dictionary< string, double > ZLabelPositions)
Scales three matrices of equal size to point vectors in space.
LinkedList< object[]> Parameters
Parameters.
override bool TrySetDefaultColor(SKColor Color)
Tries to set the default color.
override string GetBitmapClickScript(double X, double Y, object[] States)
Gets script corresponding to a point in a generated bitmap representation of the graph.
Graph3D(Variables Variables)
Base class for three-dimensional graphs.
string Title
Title for graph.
int Oversampling
Oversampling (for anti-aliasing-purposes).
ISemiGroupElement AddRight(ISemiGroupElement Element, bool _)
Tries to add an element to the current element, from the right.
LinkedList< Vector4[,]> Normals
Optional normals.
IElement MinY
Smallest Y-value.
Graph3D(Variables Variables, int? DefaultWidth, int? DefaultHeight)
Base class for three-dimensional graphs.
LinkedList< IMatrix > Y
Y-axis series.
bool ShowYAxis
If the Y-axis is to be displayed.
IElement MaxY
Largest Y-value.
override void ExportGraph(XmlWriter Output)
Exports graph specifics to XML.
string LabelX
Label for x-axis.
IElement MinZ
Smallest Z-value.
static IVector GetLabels(ref IElement Min, ref IElement Max, IEnumerable< IMatrix > Series, int ApproxNrLabels, out LabelType LabelType)
Gets label values for a series vector.
Graph3D(GraphSettings Settings)
Base class for three-dimensional graphs.
bool ShowZAxis
If the Z-axis is to be displayed.
string LabelZ
Label for z-axis.
bool ShowGrid
If the grid is to be displayed.
override ISemiGroupElementWise AddRightElementWise(ISemiGroupElementWise Element)
Tries to add an element to the current element, from the right, element-wise.
override ISemiGroupElement AddRight(ISemiGroupElement Element)
Tries to add an element to the current element, from the right.
static double[,] Scale(double[,] Matrix, double Min, double Max, double Offset, double Size)
Scales a matrix to fit a given volume.
string LabelY
Label for y-axis.
bool ShowXAxis
If the X-axis is to be displayed.
Contains information about the intensity of a light component, as used in the Phong reflection model....
Contains information about a light source, as used in the Phong reflection model. https://en....
Contains information about a material, as used in the Phong reflection model. https://en....
The Phong Shader uses the Phong Reflection model to generate colors. https://en.wikipedia....
Contains information about the current drawing area.
IElement DescaleY(double Value)
Descales a scaled value along the Y-axis.
IElement DescaleX(double Value)
Descales a scaled value along the X-axis.
Handles two-dimensional graphs.
static string ReducedXmlString(double Value)
Generates an XML value string of an element, possible with reduced resolution, to avoid unnecessary d...
bool SameScale
If the same scale should be used for all axes.
object[] ToObjectArray(IVector v)
Gets an array of objects corresponding to the elements of a vector.
static readonly DateTime referenceTimestamp
Reference time stamp when converting DateTime to Double.
static string[] LabelStrings(IVector Labels, LabelType LabelType)
Converts a vector of labels to a string array.
GraphSettings Settings
Graph settings available during creation.
static SKColor ToColor(object Object)
Converts an object to a color.
static async Task< IElement > ParseAsync(string s, Variables Variables)
Parses an element expression string.
SKColor AxisColor
Axis color.
SKColor BackgroundColor
Background color.
int ApproxNrLabelsY
Approximate number of labels along the Y-axis.
int ApproxNrLabelsX
Approximate number of labels along the X-axis.
double LabelFontSize
Label font size
SKColor GridColor
Grid color.
int Width
Width of graph, in pixels. (Default=640 pixels.)
int Height
Height of graph, in pixels. (Default=480 pixels.)
string FontName
Font name.
Base class for all nodes in a parsed script tree.
DateTime Value
DateTime value.
double Value
Double value.
PhysicalQuantity ToPhysicalQuantity()
Converts underlying object to a physical quantity.
double Magnitude
Magnitude
static IElement Encapsulate(Array Elements, bool CanEncapsulateAsMatrix, ScriptNode Node)
Encapsulates the elements of a vector.
static bool TryConvert(double From, Unit FromUnit, Unit ToUnit, out double To)
Tries to convert a magnitude in one unit to a magnitude in another.
bool IsEmpty
If the unit is empty. (A unit of only a prefix, but no factors, is not empty.)
override bool Equals(object obj)
Basic interface for all types of elements.
object AssociatedObjectValue
Associated object value.
ICollection< IElement > ChildElements
An enumeration of child elements. If the element is a scalar, this property will return null.
ISet AssociatedSet
Associated Set.
Basic interface for matrices.
int Columns
Number of columns.
IElement GetElement(int Column, int Row)
Gets an element of the matrix.
Basic interface for all types of semigroup elements.
Basic interface for all types of element-wise semigroup elements.
Basic interface for vectors.
Basic interface for all types of abelian groups.
Interface for 3D shaders.
Interface for 3D graph drawing functions.
Interface for objects that can be represented as a physical quantity.
PhysicalQuantity ToPhysicalQuantity()
Converts underlying object to a physical quantity.