Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
EllipseArc.cs
1using System;
2using System.Threading.Tasks;
3using System.Xml;
4using SkiaSharp;
6
8{
12 public class EllipseArc : FigurePoint
13 {
14 private LengthAttribute radiusX;
15 private LengthAttribute radiusY;
16 private FloatAttribute startDegrees;
17 private FloatAttribute endDegrees;
18 private FloatAttribute spanDegrees;
19 private BooleanAttribute clockwise;
20 private BooleanAttribute center;
21 private float rX;
22 private float rY;
23 private float start;
24 private float end;
25 private float span;
26 private bool clockDir;
27 private bool includeCenter;
28
35 : base(Document, Parent)
36 {
37 }
38
42 public override string LocalName => "EllipseArc";
43
48 {
49 get => this.radiusX;
50 set => this.radiusX = value;
51 }
52
57 {
58 get => this.radiusY;
59 set => this.radiusY = value;
60 }
61
66 {
67 get => this.startDegrees;
68 set => this.startDegrees = value;
69 }
70
75 {
76 get => this.endDegrees;
77 set => this.endDegrees = value;
78 }
79
84 {
85 get => this.spanDegrees;
86 set => this.spanDegrees = value;
87 }
88
93 {
94 get => this.clockwise;
95 set => this.clockwise = value;
96 }
97
102 {
103 get => this.center;
104 set => this.center = value;
105 }
106
111 public override Task FromXml(XmlElement Input)
112 {
113 this.radiusX = new LengthAttribute(Input, "radiusX", this.Document);
114 this.radiusY = new LengthAttribute(Input, "radiusY", this.Document);
115 this.startDegrees = new FloatAttribute(Input, "startDegrees", this.Document);
116 this.endDegrees = new FloatAttribute(Input, "endDegrees", this.Document);
117 this.spanDegrees = new FloatAttribute(Input, "spanDegrees", this.Document);
118 this.clockwise = new BooleanAttribute(Input, "clockwise", this.Document);
119 this.center = new BooleanAttribute(Input, "center", this.Document);
120
121 return base.FromXml(Input);
122 }
123
128 public override void ExportAttributes(XmlWriter Output)
129 {
130 base.ExportAttributes(Output);
131
132 this.radiusX?.Export(Output);
133 this.radiusY?.Export(Output);
134 this.startDegrees?.Export(Output);
135 this.endDegrees?.Export(Output);
136 this.spanDegrees?.Export(Output);
137 this.clockwise?.Export(Output);
138 this.center?.Export(Output);
139 }
140
147 public override ILayoutElement Create(Layout2DDocument Document, ILayoutElement Parent)
148 {
149 return new EllipseArc(Document, Parent);
150 }
151
156 public override void CopyContents(ILayoutElement Destination)
157 {
158 base.CopyContents(Destination);
159
160 if (Destination is EllipseArc Dest)
161 {
162 Dest.radiusX = this.radiusX?.CopyIfNotPreset(Destination.Document);
163 Dest.radiusY = this.radiusY?.CopyIfNotPreset(Destination.Document);
164 Dest.startDegrees = this.startDegrees?.CopyIfNotPreset(Destination.Document);
165 Dest.endDegrees = this.endDegrees?.CopyIfNotPreset(Destination.Document);
166 Dest.spanDegrees = this.spanDegrees?.CopyIfNotPreset(Destination.Document);
167 Dest.clockwise = this.clockwise?.CopyIfNotPreset(Destination.Document);
168 Dest.center = this.center?.CopyIfNotPreset(Destination.Document);
169 }
170 }
171
177 public override async Task DoMeasureDimensions(DrawingState State)
178 {
179 await base.DoMeasureDimensions(State);
180
181 EvaluationResult<Length> RadiusLength = await this.radiusX.TryEvaluate(State.Session);
182 if (RadiusLength.Ok)
183 State.CalcDrawingSize(RadiusLength.Result, ref this.rX, true, (ILayoutElement)this);
184 else
185 this.defined = false;
186
187 RadiusLength = await this.radiusY.TryEvaluate(State.Session);
188 if (RadiusLength.Ok)
189 State.CalcDrawingSize(RadiusLength.Result, ref this.rY, false, (ILayoutElement)this);
190 else
191 this.defined = false;
192
193 this.clockDir = await this.clockwise.Evaluate(State.Session, true);
194 this.includeCenter = await this.center.Evaluate(State.Session, false);
195
196 EvaluationResult<float> Degrees = await this.startDegrees.TryEvaluate(State.Session);
197 if (Degrees.Ok)
198 this.start = (float)Math.IEEERemainder(Degrees.Result, 360);
199 else
200 this.defined = false;
201
202 Degrees = await this.endDegrees.TryEvaluate(State.Session);
203 if (Degrees.Ok)
204 {
205 this.end = (float)Math.IEEERemainder(Degrees.Result, 360);
206
207 if (this.clockDir)
208 this.span = this.end - this.start;
209 else
210 this.span = this.start - this.end;
211
212 if (this.span < 0)
213 this.span += 360;
214 }
215 else
216 {
217 Degrees = await this.spanDegrees.TryEvaluate(State.Session);
218 if (Degrees.Ok)
219 {
220 this.span = Degrees.Result;
221 if (this.clockDir)
222 this.end = this.start + this.span;
223 else
224 this.end = this.start - this.span;
225
226 this.end = (float)Math.IEEERemainder(this.end, 360);
227 }
228 else
229 this.defined = false;
230 }
231
232 if (this.defined)
233 {
234 if (this.span >= 360)
235 {
236 this.IncludePoint(this.xCoordinate - this.rX, this.yCoordinate);
237 this.IncludePoint(this.xCoordinate + this.rX, this.yCoordinate);
238 this.IncludePoint(this.xCoordinate, this.yCoordinate - this.rY);
239 this.IncludePoint(this.xCoordinate, this.yCoordinate + this.rY);
240 }
241 else
242 {
243 float a = this.start;
244 float r = (float)Math.IEEERemainder(this.start, 90);
245 bool First = true;
246
247 this.IncludePoint(this.xCoordinate, this.yCoordinate, this.rX, this.rY, this.start);
248
249 if (this.clockDir)
250 {
251 if (this.end < this.start)
252 this.end += 360;
253
254 while (a < this.end)
255 {
256 if (First)
257 {
258 a += 90 - r;
259 First = false;
260 }
261 else
262 a += 90;
263
264 this.IncludePoint(this.xCoordinate, this.yCoordinate, this.rX, this.rY, a);
265 }
266 }
267 else
268 {
269 if (this.end > this.start)
270 this.end -= 360;
271
272 while (a > this.end)
273 {
274 if (First)
275 {
276 a -= r;
277 First = false;
278 }
279 else
280 a -= 90;
281
282 this.IncludePoint(this.xCoordinate, this.yCoordinate, this.rX, this.rY, a);
283 }
284 }
285
286 if (this.start != this.end)
287 this.IncludePoint(this.xCoordinate, this.yCoordinate, this.rX, this.rY, this.end);
288
289 if (this.includeCenter)
290 this.IncludePoint(this.xCoordinate, this.yCoordinate);
291 }
292 }
293 }
294
299 public override async Task Draw(DrawingState State)
300 {
301 if (this.defined)
302 {
303 if (this.span >= 360)
304 {
305 SKPaint Fill = await this.TryGetFill(State);
306 if (!(Fill is null))
307 State.Canvas.DrawOval(this.xCoordinate, this.yCoordinate, this.rX, this.rY, Fill);
308
309 SKPaint Pen = await this.TryGetPen(State);
310 if (!(Pen is null))
311 State.Canvas.DrawOval(this.xCoordinate, this.yCoordinate, this.rX, this.rY, Pen);
312 }
313 else
314 {
315 float Sweep = this.clockDir ? this.span : -this.span;
316 SKRect Oval = new SKRect(
317 this.xCoordinate - this.rX, this.yCoordinate - this.rY,
318 this.xCoordinate + this.rX, this.yCoordinate + this.rY);
319
320 this.start = (float)Math.IEEERemainder(this.start, 360);
321 if (this.start < 0)
322 this.start += 360;
323
324 this.end = (float)Math.IEEERemainder(this.end, 360);
325 if (this.end < 0)
326 this.end += 360;
327
328 SKPaint Fill = await this.TryGetFill(State);
329 if (!(Fill is null))
330 State.Canvas.DrawArc(Oval, this.start, Sweep, this.includeCenter, Fill);
331
332 SKPaint Pen = await this.TryGetPen(State);
333 if (!(Pen is null))
334 State.Canvas.DrawArc(Oval, this.start, Sweep, this.includeCenter, Pen);
335 }
336 }
337
338 await base.Draw(State);
339 }
340
345 public override void ExportStateAttributes(XmlWriter Output)
346 {
347 base.ExportStateAttributes(Output);
348
349 this.radiusX?.ExportState(Output);
350 this.radiusY?.ExportState(Output);
351 this.startDegrees?.ExportState(Output);
352 this.endDegrees?.ExportState(Output);
353 this.spanDegrees?.ExportState(Output);
354 this.clockwise?.ExportState(Output);
355 this.center?.ExportState(Output);
356 }
357
358 }
359}
Contains a 2D layout document.
void Export(XmlWriter Output)
Exports the attribute.
Definition: Attribute.cs:187
void ExportState(XmlWriter Output)
Exports the state of the attribute.
Definition: Attribute.cs:199
static async Task< EvaluationResult< T > > TryEvaluate(Attribute< T > Attribute, Variables Session)
Tries to evaluate the attribute value.
Definition: Attribute.cs:256
BooleanAttribute CopyIfNotPreset(Layout2DDocument ForDocument)
Copies the attribute object if undefined, or defined by an expression. Returns a reference to itself,...
FloatAttribute CopyIfNotPreset(Layout2DDocument ForDocument)
Copies the attribute object if undefined, or defined by an expression. Returns a reference to itself,...
LengthAttribute CopyIfNotPreset(Layout2DDocument ForDocument)
Copies the attribute object if undefined, or defined by an expression. Returns a reference to itself,...
SKCanvas Canvas
Current drawing canvas.
Variables Session
Current session.
Definition: DrawingState.cs:91
void CalcDrawingSize(Length L, ref float Size, bool Horizontal, ILayoutElement Element)
Converts a defined length to drawing size.
FloatAttribute SpanDegreesAttribute
Span Degrees
Definition: EllipseArc.cs:84
override void ExportStateAttributes(XmlWriter Output)
Exports the local attributes of the current element.
Definition: EllipseArc.cs:345
override void CopyContents(ILayoutElement Destination)
Copies contents (attributes and children) to the destination element.
Definition: EllipseArc.cs:156
FloatAttribute EndDegreesAttribute
End Degrees
Definition: EllipseArc.cs:75
override Task FromXml(XmlElement Input)
Populates the element (including children) with information from its XML definition.
Definition: EllipseArc.cs:111
override string LocalName
Local name of type of element.
Definition: EllipseArc.cs:42
override async Task DoMeasureDimensions(DrawingState State)
Measures layout entities and defines unassigned properties, related to dimensions.
Definition: EllipseArc.cs:177
EllipseArc(Layout2DDocument Document, ILayoutElement Parent)
An ellipse arc
Definition: EllipseArc.cs:34
BooleanAttribute ClockwiseAttribute
Clockwise
Definition: EllipseArc.cs:93
override void ExportAttributes(XmlWriter Output)
Exports attributes to XML.
Definition: EllipseArc.cs:128
BooleanAttribute CenterAttribute
Include center point
Definition: EllipseArc.cs:102
override ILayoutElement Create(Layout2DDocument Document, ILayoutElement Parent)
Creates a new instance of the layout element.
Definition: EllipseArc.cs:147
override async Task Draw(DrawingState State)
Draws layout entities.
Definition: EllipseArc.cs:299
FloatAttribute StartDegreesAttribute
Start Degrees
Definition: EllipseArc.cs:66
async Task< SKPaint > TryGetPen(DrawingState State)
Tries to get the pen associated with the element, if one is defined.
Definition: Figure.cs:111
async Task< SKPaint > TryGetFill(DrawingState State)
Tries to get the filling of the figure, if one is defined.
Definition: Figure.cs:130
Abstract base class for figures based on a point.
Definition: FigurePoint.cs:11
void IncludePoint(float X, float Y, float RX, float RY, float Angle)
Includes a point in the area measurement.
Layout2DDocument Document
Layout document.
bool defined
If element is well-defined.
Base interface for all layout elements.
Layout2DDocument Document
Layout document.