Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
CircleArc.cs
1using System;
2using System.Threading.Tasks;
3using System.Xml;
4using SkiaSharp;
6
8{
12 public class CircleArc : FigurePoint
13 {
14 private LengthAttribute radius;
15 private FloatAttribute startDegrees;
16 private FloatAttribute endDegrees;
17 private FloatAttribute spanDegrees;
18 private BooleanAttribute clockwise;
19 private BooleanAttribute center;
20 private float r;
21 private float start;
22 private float end;
23 private float span;
24 private bool clockDir;
25 private bool includeCenter;
26
32 public CircleArc(Layout2DDocument Document, ILayoutElement Parent)
33 : base(Document, Parent)
34 {
35 }
36
40 public override string LocalName => "CircleArc";
41
46 {
47 get => this.radius;
48 set => this.radius = value;
49 }
50
55 {
56 get => this.startDegrees;
57 set => this.startDegrees = value;
58 }
59
64 {
65 get => this.endDegrees;
66 set => this.endDegrees = value;
67 }
68
73 {
74 get => this.spanDegrees;
75 set => this.spanDegrees = value;
76 }
77
82 {
83 get => this.clockwise;
84 set => this.clockwise = value;
85 }
86
91 {
92 get => this.center;
93 set => this.center = value;
94 }
95
100 public override Task FromXml(XmlElement Input)
101 {
102 this.radius = new LengthAttribute(Input, "radius", this.Document);
103 this.startDegrees = new FloatAttribute(Input, "startDegrees", this.Document);
104 this.endDegrees = new FloatAttribute(Input, "endDegrees", this.Document);
105 this.spanDegrees = new FloatAttribute(Input, "spanDegrees", this.Document);
106 this.clockwise = new BooleanAttribute(Input, "clockwise", this.Document);
107 this.center = new BooleanAttribute(Input, "center", this.Document);
108
109 return base.FromXml(Input);
110 }
111
116 public override void ExportAttributes(XmlWriter Output)
117 {
118 base.ExportAttributes(Output);
119
120 this.radius?.Export(Output);
121 this.startDegrees?.Export(Output);
122 this.endDegrees?.Export(Output);
123 this.spanDegrees?.Export(Output);
124 this.clockwise?.Export(Output);
125 this.center?.Export(Output);
126 }
127
134 public override ILayoutElement Create(Layout2DDocument Document, ILayoutElement Parent)
135 {
136 return new CircleArc(Document, Parent);
137 }
138
143 public override void CopyContents(ILayoutElement Destination)
144 {
145 base.CopyContents(Destination);
146
147 if (Destination is CircleArc Dest)
148 {
149 Dest.radius = this.radius?.CopyIfNotPreset(Destination.Document);
150 Dest.startDegrees = this.startDegrees?.CopyIfNotPreset(Destination.Document);
151 Dest.endDegrees = this.endDegrees?.CopyIfNotPreset(Destination.Document);
152 Dest.spanDegrees = this.spanDegrees?.CopyIfNotPreset(Destination.Document);
153 Dest.clockwise = this.clockwise?.CopyIfNotPreset(Destination.Document);
154 Dest.center = this.center?.CopyIfNotPreset(Destination.Document);
155 }
156 }
157
163 public override async Task DoMeasureDimensions(DrawingState State)
164 {
165 await base.DoMeasureDimensions(State);
166
167 EvaluationResult<Length> RadiusLength = await this.radius.TryEvaluate(State.Session);
168 if (RadiusLength.Ok)
169 State.CalcDrawingSize(RadiusLength.Result, ref this.r, true, this);
170 else
171 this.defined = false;
172
173 this.clockDir = await this.clockwise.Evaluate(State.Session, true);
174 this.includeCenter = await this.center.Evaluate(State.Session, false);
175
176 EvaluationResult<float> Degrees = await this.startDegrees.TryEvaluate(State.Session);
177 if (Degrees.Ok)
178 this.start = (float)Math.IEEERemainder(Degrees.Result, 360);
179 else
180 this.defined = false;
181
182 Degrees = await this.endDegrees.TryEvaluate(State.Session);
183 if (Degrees.Ok)
184 {
185 this.end = (float)Math.IEEERemainder(Degrees.Result, 360);
186
187 if (this.clockDir)
188 this.span = this.end - this.start;
189 else
190 this.span = this.start - this.end;
191
192 if (this.span < 0)
193 this.span += 360;
194 }
195 else
196 {
197 Degrees = await this.spanDegrees.TryEvaluate(State.Session);
198 if (Degrees.Ok)
199 {
200 this.span = Degrees.Result;
201 if (this.clockDir)
202 this.end = this.start + this.span;
203 else
204 this.end = this.start - this.span;
205
206 this.end = (float)Math.IEEERemainder(this.end, 360);
207 }
208 else
209 this.defined = false;
210 }
211
212 if (this.defined)
213 {
214 if (this.span >= 360)
215 {
216 this.IncludePoint(this.xCoordinate - this.r, this.yCoordinate);
217 this.IncludePoint(this.xCoordinate + this.r, this.yCoordinate);
218 this.IncludePoint(this.xCoordinate, this.yCoordinate - this.r);
219 this.IncludePoint(this.xCoordinate, this.yCoordinate + this.r);
220 }
221 else
222 {
223 float a = this.start;
224 float r = (float)Math.IEEERemainder(this.start, 90);
225 bool First = true;
226
227 this.IncludePoint(this.xCoordinate, this.yCoordinate, this.r, this.r, this.start);
228
229 if (this.clockDir)
230 {
231 if (this.end < this.start)
232 this.end += 360;
233
234 while (a < this.end)
235 {
236 if (First)
237 {
238 a += 90 - r;
239 First = false;
240 }
241 else
242 a += 90;
243
244 this.IncludePoint(this.xCoordinate, this.yCoordinate, this.r, this.r, a);
245 }
246 }
247 else
248 {
249 if (this.end > this.start)
250 this.end -= 360;
251
252 while (a > this.end)
253 {
254 if (First)
255 {
256 a -= r;
257 First = false;
258 }
259 else
260 a -= 90;
261
262 this.IncludePoint(this.xCoordinate, this.yCoordinate, this.r, this.r, a);
263 }
264 }
265
266 if (this.start != this.end)
267 this.IncludePoint(this.xCoordinate, this.yCoordinate, this.r, this.r, this.end);
268
269 if (this.includeCenter)
270 this.IncludePoint(this.xCoordinate, this.yCoordinate);
271 }
272 }
273 }
274
279 public override async Task Draw(DrawingState State)
280 {
281 if (this.defined)
282 {
283 if (this.span >= 360)
284 {
285 SKPaint Fill = await this.TryGetFill(State);
286 if (!(Fill is null))
287 State.Canvas.DrawCircle(this.xCoordinate, this.yCoordinate, this.r, Fill);
288
289 SKPaint Pen = await this.TryGetPen(State);
290 if (!(Pen is null))
291 State.Canvas.DrawCircle(this.xCoordinate, this.yCoordinate, this.r, Pen);
292 }
293 else
294 {
295 float Sweep = this.clockDir ? this.span : -this.span;
296 SKRect Oval = new SKRect(
297 this.xCoordinate - this.r, this.yCoordinate - this.r,
298 this.xCoordinate + this.r, this.yCoordinate + this.r);
299
300 this.start = (float)Math.IEEERemainder(this.start, 360);
301 if (this.start < 0)
302 this.start += 360;
303
304 this.end = (float)Math.IEEERemainder(this.end, 360);
305 if (this.end < 0)
306 this.end += 360;
307
308 SKPaint Fill = await this.TryGetFill(State);
309 if (!(Fill is null))
310 State.Canvas.DrawArc(Oval, this.start, Sweep, this.includeCenter, Fill);
311
312 SKPaint Pen = await this.TryGetPen(State);
313 if (!(Pen is null))
314 State.Canvas.DrawArc(Oval, this.start, Sweep, this.includeCenter, Pen);
315 }
316 }
317
318 await base.Draw(State);
319 }
320
325 public override void ExportStateAttributes(XmlWriter Output)
326 {
327 base.ExportStateAttributes(Output);
328
329 this.radius?.ExportState(Output);
330 this.startDegrees?.ExportState(Output);
331 this.endDegrees?.ExportState(Output);
332 this.spanDegrees?.ExportState(Output);
333 this.clockwise?.ExportState(Output);
334 this.center?.ExportState(Output);
335 }
336
337 }
338}
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.
override void ExportStateAttributes(XmlWriter Output)
Exports the local attributes of the current element.
Definition: CircleArc.cs:325
FloatAttribute SpanDegreesAttribute
Span Degrees
Definition: CircleArc.cs:73
override ILayoutElement Create(Layout2DDocument Document, ILayoutElement Parent)
Creates a new instance of the layout element.
Definition: CircleArc.cs:134
FloatAttribute StartDegreesAttribute
Start Degrees
Definition: CircleArc.cs:55
BooleanAttribute CenterAttribute
Include center point
Definition: CircleArc.cs:91
override void ExportAttributes(XmlWriter Output)
Exports attributes to XML.
Definition: CircleArc.cs:116
FloatAttribute EndDegreesAttribute
End Degrees
Definition: CircleArc.cs:64
CircleArc(Layout2DDocument Document, ILayoutElement Parent)
A circle arc
Definition: CircleArc.cs:32
override Task FromXml(XmlElement Input)
Populates the element (including children) with information from its XML definition.
Definition: CircleArc.cs:100
BooleanAttribute ClockwiseAttribute
Clockwise
Definition: CircleArc.cs:82
override async Task Draw(DrawingState State)
Draws layout entities.
Definition: CircleArc.cs:279
override void CopyContents(ILayoutElement Destination)
Copies contents (attributes and children) to the destination element.
Definition: CircleArc.cs:143
override string LocalName
Local name of type of element.
Definition: CircleArc.cs:40
override async Task DoMeasureDimensions(DrawingState State)
Measures layout entities and defines unassigned properties, related to dimensions.
Definition: CircleArc.cs:163
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.