|
|
782bf6 |
using System;
|
|
|
782bf6 |
|
|
|
782bf6 |
namespace EllipseTruncate {
|
|
|
782bf6 |
public class ActiveAngleRange {
|
|
|
782bf6 |
public double width = 0.1;
|
|
|
782bf6 |
|
|
|
782bf6 |
public Point point;
|
|
|
782bf6 |
public double radius;
|
|
|
782bf6 |
public AngleRange.Entry current;
|
|
|
782bf6 |
public AngleRange a = new AngleRange();
|
|
|
782bf6 |
public AngleRange b = new AngleRange();
|
|
|
782bf6 |
|
|
|
782bf6 |
public ActiveAngleRange(Point point, double radius) {
|
|
|
782bf6 |
this.point = point;
|
|
|
782bf6 |
this.radius = radius;
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
public void add() {
|
|
|
782bf6 |
a.add(current);
|
|
|
782bf6 |
current = new AngleRange.Entry();
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
public void xor() {
|
|
|
782bf6 |
a.xor(current);
|
|
|
782bf6 |
current = new AngleRange.Entry();
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
public void subtract() {
|
|
|
782bf6 |
a.subtract(current);
|
|
|
782bf6 |
current = new AngleRange.Entry();
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
public void scale(Cairo.Context context, double level = 1.0) {
|
|
|
782bf6 |
double k = Math.Pow(1.0 + 1.5*width, level);
|
|
|
782bf6 |
context.Scale(k, k);
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
public void draw(Cairo.Context context, uint a0, uint a1, double level = 0.0) {
|
|
|
782bf6 |
if (a0 == a1) return;
|
|
|
782bf6 |
|
|
|
782bf6 |
context.Save();
|
|
|
782bf6 |
scale(context, level);
|
|
|
782bf6 |
context.LineWidth = width;
|
|
|
782bf6 |
double aa0 = AngleRange.toDouble(a0);
|
|
|
782bf6 |
double aa1 = AngleRange.toDouble(a1);
|
|
|
782bf6 |
if (a1 < a0) aa1 += AngleRange.period;
|
|
|
782bf6 |
if (aa1 < aa0) return;
|
|
|
782bf6 |
|
|
|
782bf6 |
context.Arc(0.0, 0.0, 1.0, aa0, aa1);
|
|
|
782bf6 |
context.Stroke();
|
|
|
782bf6 |
context.Restore();
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
public void draw(Cairo.Context context, AngleRange r, double level = 0.0) {
|
|
|
782bf6 |
context.Save();
|
|
|
782bf6 |
scale(context, level);
|
|
|
782bf6 |
if (r.isEmpty()) {
|
|
|
782bf6 |
context.LineWidth = 0.25*width;
|
|
|
782bf6 |
context.SetDash(new double[] { 0.1, 0.02 }, 0.0);
|
|
|
782bf6 |
context.Arc(0.0, 0.0, 1.0, 0.0, 2.0*Math.PI);
|
|
|
782bf6 |
context.Stroke();
|
|
|
782bf6 |
} else
|
|
|
782bf6 |
if (r.isFull()) {
|
|
|
782bf6 |
context.LineWidth = width;
|
|
|
782bf6 |
context.Arc(0.0, 0.0, 1.0, 0.0, 2.0*Math.PI);
|
|
|
782bf6 |
context.Stroke();
|
|
|
782bf6 |
context.LineWidth = 0.25*width;
|
|
|
782bf6 |
context.SetDash(new double[] { 0.1, 0.03 }, 0.0);
|
|
|
782bf6 |
context.Arc(0.0, 0.0, 1.0, 0.0, 2.0*Math.PI);
|
|
|
782bf6 |
context.Stroke();
|
|
|
782bf6 |
} else {
|
|
|
782bf6 |
context.LineWidth = 0.25*width;
|
|
|
782bf6 |
context.Arc(0.0, 0.0, 1.0, 0.0, 2.0*Math.PI);
|
|
|
782bf6 |
context.Stroke();
|
|
|
782bf6 |
bool f = r.flip;
|
|
|
782bf6 |
uint prev = r.angles[r.angles.Count - 1];
|
|
|
782bf6 |
foreach(uint a in r.angles) {
|
|
|
782bf6 |
if (f) draw(context, prev, a);
|
|
|
782bf6 |
prev = a; f = !f;
|
|
|
782bf6 |
}
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
if (!r.check()) {
|
|
|
782bf6 |
context.LineWidth = width;
|
|
|
782bf6 |
context.SetDash(new double[] { 0.1, 0.02 }, 0.0);
|
|
|
782bf6 |
context.Arc(0.0, 0.0, 1.0, 0.0, 2.0*Math.PI);
|
|
|
782bf6 |
context.Stroke();
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
context.Restore();
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|
|
|
782bf6 |
public void draw(Cairo.Context context) {
|
|
|
782bf6 |
context.Save();
|
|
|
782bf6 |
context.Translate(point.x, point.y);
|
|
|
782bf6 |
context.Scale(radius, radius);
|
|
|
782bf6 |
|
|
|
782bf6 |
AngleRange x = new AngleRange();
|
|
|
782bf6 |
|
|
|
782bf6 |
// back circle
|
|
|
782bf6 |
context.SetSourceRGBA(1.0, 0.0, 0.0, 0.1);
|
|
|
782bf6 |
context.Arc(0.0, 0.0, 1.0, 0.0, 2.0*Math.PI);
|
|
|
782bf6 |
context.Fill();
|
|
|
782bf6 |
|
|
|
782bf6 |
// a
|
|
|
782bf6 |
context.SetSourceRGBA(0.0, 0.0, 0.0, 0.5);
|
|
|
782bf6 |
draw(context, a);
|
|
|
782bf6 |
|
|
|
782bf6 |
// b
|
|
|
782bf6 |
context.SetSourceRGBA(0.0, 0.0, 1.0, 0.5);
|
|
|
782bf6 |
draw(context, b, 1.0);
|
|
|
782bf6 |
|
|
|
782bf6 |
// current
|
|
|
782bf6 |
context.SetSourceRGBA(0.0, 0.0, 1.0, 0.5);
|
|
|
782bf6 |
if (!current.isEmpty())
|
|
|
782bf6 |
draw(context, current.a0, current.a1);
|
|
|
782bf6 |
|
|
|
782bf6 |
// !a
|
|
|
782bf6 |
context.SetSourceRGBA(0.5, 0.5, 0.5, 0.5);
|
|
|
782bf6 |
x.set(a); x.invert();
|
|
|
782bf6 |
draw(context, x, -1.0);
|
|
|
782bf6 |
|
|
|
782bf6 |
scale(context);
|
|
|
782bf6 |
|
|
|
782bf6 |
// a xor b
|
|
|
782bf6 |
scale(context);
|
|
|
782bf6 |
context.SetSourceRGBA(0.0, 0.5, 0.0, 0.5);
|
|
|
782bf6 |
x.set(a);
|
|
|
782bf6 |
x.xor(b);
|
|
|
782bf6 |
draw(context, x);
|
|
|
782bf6 |
|
|
|
782bf6 |
// a | b
|
|
|
782bf6 |
scale(context);
|
|
|
782bf6 |
context.SetSourceRGBA(0.0, 0.5, 0.0, 0.5);
|
|
|
782bf6 |
x.set(a);
|
|
|
782bf6 |
x.add(b);
|
|
|
782bf6 |
draw(context, x);
|
|
|
782bf6 |
|
|
|
782bf6 |
// a & ~b
|
|
|
782bf6 |
scale(context);
|
|
|
782bf6 |
context.SetSourceRGBA(0.0, 0.5, 0.0, 0.5);
|
|
|
782bf6 |
x.set(a);
|
|
|
782bf6 |
x.subtract(b);
|
|
|
782bf6 |
draw(context, x);
|
|
|
782bf6 |
|
|
|
782bf6 |
// a & b
|
|
|
782bf6 |
scale(context);
|
|
|
782bf6 |
context.SetSourceRGBA(0.0, 0.5, 0.0, 0.5);
|
|
|
782bf6 |
x.set(a);
|
|
|
782bf6 |
x.intersect(b);
|
|
|
782bf6 |
draw(context, x);
|
|
|
782bf6 |
|
|
|
782bf6 |
context.Restore();
|
|
|
782bf6 |
}
|
|
|
782bf6 |
}
|
|
|
782bf6 |
}
|
|
|
782bf6 |
|