diff --git a/WordCloudCalculator/Contract/Range.cs b/WordCloudCalculator/Contract/Range.cs
index 43cfa13..e7424da 100644
--- a/WordCloudCalculator/Contract/Range.cs
+++ b/WordCloudCalculator/Contract/Range.cs
@@ -2,25 +2,29 @@
namespace WordCloudCalculator.Contract
{
- ///
- /// Defines Boundaries and provides some related calculation methods
- ///
- public struct Range
- {
- private double _min;
- private double _max;
+ ///
+ /// Defines Boundaries and provides some related calculation methods
+ ///
+ public struct Range
+ {
+ private double _min;
+ private double _max;
+ //private double _step ;
- public Range(double min, double max)
- {
- _max = max;
- _min = min;
- if(!IsValid) throw new Exception("Invalid Range!");
- }
-
- ///
- /// Lower Bound
- ///
- public double Min
+ public Range(double min, double max /*, step = 1.0*/ )
+ {
+ //_step = 1.0;
+ //_max = Convert.ToInt32(max / _step) * _step;
+ //_min = Convert.ToInt32(min / _step) * _step;
+ _max = max;
+ _min = min;
+ if (min > max) throw new Exception("Invalid Range!");
+ }
+ //private double InStep(double x, double s) => { return Convert.ToInt32(x / s) * s };
+ ///
+ /// Lower Bound
+ ///
+ public double Min
{
get { return _min; }
set
@@ -38,7 +42,7 @@ public double Max
get { return _max; }
set
{
- if (value < Min) throw new Exception("Maximum cannot be lesser than Minimum!");
+ if (!IsValid) throw new Exception("Maximum cannot be lesser than Minimum!");
_max = value;
}
}
@@ -52,10 +56,10 @@ public double Max
///
public bool Includes(double value) => Min <= value && value <= Max;
- ///
- /// Checks if bound relation is correct
- ///
- public bool IsValid => Max >= Min;
+ ///
+ /// Checks if bound relation is correct
+ ///
+ public bool IsValid => Max >= Min;
///
/// Calculates the relative range value of a given value of an other Range
@@ -65,7 +69,7 @@ public double Max
/// Relative Range Value
public double CalculateRelativeValue(Range valueRange, double currentValue)
{
- return Min + (currentValue - valueRange.Min)*Amplitude/valueRange.Amplitude;
+ return Min + (currentValue - valueRange.Min) * Amplitude / valueRange.Amplitude;
}
}
}
\ No newline at end of file
diff --git a/WordCloudCalculator/Contract/Word/VisualizedWord.cs b/WordCloudCalculator/Contract/Word/VisualizedWord.cs
index c798783..594a4ac 100644
--- a/WordCloudCalculator/Contract/Word/VisualizedWord.cs
+++ b/WordCloudCalculator/Contract/Word/VisualizedWord.cs
@@ -33,6 +33,8 @@ public VisualizedWord(IWord word)
/// Defines how strong the word should be displayed [0..1]
///
public double Opacity { get; set; }
- public override string ToString() => $"{Text}, Position({Position}), FontSize({FontSize}) Opacity = {Opacity:N1}";
- }
+ public Size Size { get; set; }
+ public override string ToString() => $"{Text}, Position({Position}), Size({Size}), FontSize({FontSize}) Opacity = {Opacity:N1}";
+
+ }
}
\ No newline at end of file
diff --git a/WordCloudCalculator/ExtractingWordCloudCalculator/CircleAppearenceCalculationMethod.cs b/WordCloudCalculator/ExtractingWordCloudCalculator/CircleAppearenceCalculationMethod.cs
index ea40192..e6066b5 100644
--- a/WordCloudCalculator/ExtractingWordCloudCalculator/CircleAppearenceCalculationMethod.cs
+++ b/WordCloudCalculator/ExtractingWordCloudCalculator/CircleAppearenceCalculationMethod.cs
@@ -14,86 +14,287 @@ public class CircleAppearenceCalculationMethod : IWordAppearenceCalculationMetho
public IWordCloudAppearenceArguments Arguments { get; set; }
public double MaxWeight { get; set; }
public bool CanAddWords { get; private set; } = true;
- public int StopAfterWords { get; set; } = 10;
+ public int StopAfterWords { get; set; } = 300;
+ public int Radius { get; set; } = 1;
+ public int Sectors{ get; set; } = 64;
//public List Polygons { get; private set; }
- public List Taken { get; private set; }
-
- public double Area(Rect r) {
- return (r.BottomRight - r.BottomLeft) * (r.BottomRight - r.TopRight);
+ public List Taken { get; private set; } = new List();
+ private int Cnt { get; set; } = 0;
+ private double pos;
+
+ public double CalculateRelativeValue(Range Range, double Weight, double Step, double Multiplier = 1) {
+ //= Convert.ToInt32((Range.Min / Range.Max * Weight % Range.Max + Range.Min) / Step) * Step,
+ //var ratio = Range.CalculateRelativeValue(Range, Weight);
+ var ratio = Range.Min / Range.Max * Weight /*/ (Range.Max - Range.Min)*/;
+ var i = (ratio % (Range.Max - Range.Min) + Range.Min) ;
+ var r = Convert.ToInt32(i / Step) * Step;
+if(r > Range.Max)
+ {
+ ;
+ }
+ return r;
}
+<<<<<<< HEAD
+
private Point GetSpiralPoint(double position, double radius = 7) {
var tau = 2 * Math.PI;
double mult = position / tau * radius;
double angle = position % tau;
return new Point((int)(mult * Math.Sin(angle)), (int)(mult * Math.Cos(angle)));
+=======
+ public double Area(Rect r) { // (Groß-Klein)^2
+ if (r.IsEmpty) { return 0; }
+ return (r.Bottom - r.Top) * (r.Right - r.Left);
+ }
+ public bool RectIntersectsRect(Rect r1, Rect r2) {
+ var p1 = new Point(r1.Left, r1.Top);
+ var p2 = new Point(r1.Right, r1.Top);
+ var p3 = new Point(r1.Left, r1.Bottom);
+ var p4 = new Point(r1.Right, r1.Bottom);
+ if (PointIntersectsRect(p1, r2)) return true;
+ if (PointIntersectsRect(p2, r2)) return true;
+ if (PointIntersectsRect(p3, r2)) return true;
+ if (PointIntersectsRect(p4, r2)) return true;
+ return false;
+ }
+ public bool PointIntersectsRect(Point p, Rect r2)
+ {
+ if ( ( p.Y >= r2.Top && p.Y <= r2.Bottom) && (p.X <= r2.Right && p.X >= r2.Left) ) {
+ return true;
+ }
+ return false;
+>>>>>>> origin
}
-
- public VisualizedWord CalculateWordAppearence( IWeightedWord word, int itemIndex/*, VisualizedWord preDecessors*/ ) {
+ public VisualizedWord CalculateWordAppearence(IWeightedWord word, int itemIndex/*, VisualizedWord preDecessors*/ ) {
+
//Ausdehnung
var size = Arguments.WordSizeCalculator(word.Text, CalculateRelativeValue(Arguments.FontSizeRange, word.Weight));
- var s = new System.Windows.Size(size.Width, size.Height);
+ var s = new System.Windows.Size(size.Width + Arguments.WordMargin.Left + Arguments.WordMargin.Right,
+ size.Height+ Arguments.WordMargin.Top + Arguments.WordMargin.Bottom);
+
//Startpunkt ermitteln
var p = new Point();
+
if (itemIndex == 0) { //vll auch (0,0), später!
- //var p = new Point(
- // (Arguments.PanelSize.Width + s.Width) / 2,
- // (Arguments.PanelSize.Height + s.Width) / 2
- //);
- p.X = (Arguments.PanelSize.Width + s.Width) / 2;
- p.Y = (Arguments.PanelSize.Height + s.Width) / 2;
+ p.X = 0 - Arguments.WordMargin.Left;
+ p.Y = 0 - Arguments.WordMargin.Top;
+ pos = 0;
} else {
- //var p = new Point();
- //p=getpoint()
+ p = GetSpiralPoint(pos/*, radius = 2*/);
+ p.X -= Arguments.WordMargin.Left;
+ p.Y -= Arguments.WordMargin.Top;
+
}
+
//mach' ein Rechteck d'raus
- var rectangle = new Rect() {
+ var rectangle = new System.Windows.Rect() {
Location = p,
Size = s
};
+ var rectgeom = rectangle;//geometrisch
//bis Platz gefunden
var found = false;
+ var nofound = false;
+
+ var offsetvector = new System.Windows.Vector(
+ Arguments.PanelSize.Width / 2,
+ Arguments.PanelSize.Height / 2
+ );
//Kollisionserkennung: über Vorgänger iterieren
//Teste Position (x,y) ist frei für Wort mit Größe size
+<<<<<<< HEAD
while ( !found ) {
if (itemIndex > 0) { //keine Kollision bei 1. Element
var intersect = new Rect();
foreach (Rect r in Taken) {
intersect = Rect.Intersect(rectangle, r);
- if (intersect.IsEmpty) { // darf ich benutzen
+ if (intersect == System.Windows.Rect.Empty) { // darf ich benutzen
found = true; // mit rumschleifen aufhören
break;
} else { // Platz belegt
- // neuen Punkt finden
+ // neuen Punkt finden
+
+
+ Point spiralPoint = GetSpiralPoint(r.Left);
+ int offsetX = Console.WindowWidth/100;
+ int offsetY = Console.WindowHeight/100;
+ var testPoint = new Point((int)(spiralPoint.X + offsetX), (int)(spiralPoint.Y - offsetY));
+
+
+
+
+
+
}
+=======
+ var intersect = new Rect();
+ var tau = 2* Math.PI;
+ var itemCnt = 0;
+
+ rectgeom.Offset(offsetvector);
+ while ( !((itemIndex <= 0) || found ) ) {
+ nofound = false;
+ foreach (Rect r in Taken) {
+ var f = this.RectIntersectsRect(rectangle, r);
+ if (f) { // darf ich benutzen, anliegende kanten werden als intersected bewertet
+ nofound = true;
+>>>>>>> origin
}
+ }
+ if ( nofound
+ || rectgeom.Left < 0 || rectgeom.Left >= Arguments.PanelSize.Width
+ || rectgeom.Top < 0 || rectgeom.Top >= Arguments.PanelSize.Height
+ || rectgeom.Right < 0 || rectgeom.Right >= Arguments.PanelSize.Width
+ || rectgeom.Bottom < 0 || rectgeom.Bottom >= Arguments.PanelSize.Height
+ ) {
+ nofound = true;
}
+<<<<<<< HEAD
+
};
//bzw. of Position (x,y) bis Position (x+size.Width,y+size.Height) frei/leer ist
//wenn nicht, neue Position anhand Spirale a(r,phi) => a(x,y)
+ Taken.Add(rectangle); //platzieren
+=======
+ // Platz belegt
+ // neue Postion anhand Fläche bestimmen, min Schritte von 3,6°
+>>>>>>> origin
- var visualizedTag = new VisualizedWord(word) {
- Position = new Position(p.X, p.Y),
- Opacity = CalculateRelativeValue(Arguments.OpacityRange, word.Weight)
- };
+ if (nofound) {
+ itemCnt++;
+ Cnt++;
+ var a = (this.Area(intersect)/this.Area(rectgeom));
+ pos += tau/Sectors + a;
+ p = GetSpiralPoint(pos);//this.Radius
+ p.X -= (Arguments.WordMargin.Left );
+ p.Y -= (Arguments.WordMargin.Top );
+ //rectangle.Width += Arguments.WordMargin.Left + Arguments.WordMargin.Right;
+ //rectangle.Height += Arguments.WordMargin.Top + Arguments.WordMargin.Bottom;
+ rectangle.Location=p;
+ rectgeom = rectangle;
+ rectgeom.Offset(offsetvector);
+ //nofound = false;
+ } else {
+ found = true;
+ itemCnt = 0;
+ if (itemIndex > 44) {
+ ;
+ }
+ }
+ if (itemCnt > Sectors * 2) {
+ break;
+ }
+ }
+
+ //bzw. of Position (x,y) bis Position (x+size.Width,y+size.Height) frei/leer ist
+ //wenn nicht, neue Position anhand Spirale a(r,phi) => a(x,y)
+
+ //var durch = 0;
+ //foreach (Rect r in Taken)
+ //{
+ // Console.Write(durch);
+ // Console.Write(":");
+ // Console.Write(r.TopLeft);
+ // Console.Write("-");
+ // Console.Write(r.TopRight);
+ // Console.Write("\r\n");
+ // durch++;
+ //};
+
+ // raise flag to stop new Words
+ if (
+ (StopAfterWords >= 1 && itemIndex >= (StopAfterWords - 1))
+ || !this.RectIntersectsRect(rectgeom, new Rect(new Point(0, 0), new System.Windows.Size(Arguments.PanelSize.Width, Arguments.PanelSize.Height)))
+ ) {
+ CanAddWords = false;
+ }
//rechtecke für nächsten Durchlauf speichern
- Taken.Add( rectangle );
+ if (!rectangle.IsEmpty || CanAddWords) {
+ Taken.Add(rectangle);
- if (StopAfterWords > 0 && itemIndex == (StopAfterWords - 1)) {
- CanAddWords = false;
- }
+ var vergl = new Range(Arguments.FontSizeRange.Min, Arguments.FontSizeRange.Max/*, 0.5*/).CalculateRelativeValue(Arguments.FontSizeRange, word.Weight);
+ return new VisualizedWord(word) {
+ Size = new Contract.Visualization.Size(rectangle.Width, rectangle.Height),
+ //FontSize = Convert.ToInt32((Arguments.FontSizeRange.Min / Arguments.FontSizeRange.Max * word.Weight % Arguments.FontSizeRange.Max + Arguments.FontSizeRange.Min) / 0.5) * 0.5,
+ //FontSize = Arguments.FontSizeRange.CalculateRelativeValue(Arguments.FontSizeRange, word.Weight/*, 0.5, 1*/),
+ FontSize = CalculateRelativeValue(Arguments.FontSizeRange, word.Weight, 0.5, 1),
+ Position = new Position(rectangle.Top, rectangle.Left),
+ //Opacity = (Arguments.OpacityRange.Min / Arguments.OpacityRange.Max * word.Weight % 150 + Arguments.OpacityRange.Min) / 150 //CalculateRelativeValue(Arguments.OpacityRange, word.Weight, double Step)
+ Opacity = this.CalculateRelativeValue(Arguments.OpacityRange, word.Weight, 0.1, 1)
+ //Opacity = Arguments.OpacityRange.CalculateRelativeValue(Arguments.OpacityRange, word.Weight/*, 0.1, 1*/)
+ }
+ ;
+ } else { return new VisualizedWord(word); }
- return visualizedTag;
}
private double CalculateRelativeValue(Range range, double current) {
return range.CalculateRelativeValue(new Range(0, MaxWeight), current);
}
- }
+
+ private Point GetSpiralPoint(double position, double radius=2)
+ {
+ var tau = 2 * Math.PI;
+
+ double mult = position / tau * radius;
+ double angle = position % tau;
+
+ //Console.Write((int)(mult * Math.Sin(angle)));
+ //Console.Write((int)(mult * Math.Cos(angle)));
+ //Console.Write(" /-/ ");
+
+ return new Point((int)(mult * Math.Sin(angle)), (int)(mult * Math.Cos(angle)));
+ }
+/* d3-cloud inspired
+ * s.a. https://github.com/jasondavies/d3-cloud/blob/master/index.js
+ */
+ private Point archimedeanSpiral(System.Windows.Size size) {
+ //ohne lambda
+ var e = size.Width / size.Height;
+ var r = new Random();
+ //var t = new Random() { return this.NextDouble() } < .5 ? 1 : -1;
+ var t = r.NextDouble() < .5 ? 1 : -1;
+ //Console.Write("e="); Console.Write(e); Console.Write("//");
+ //t /= .1;
+ return new System.Windows.Point(e * (t /= 10) * Math.Cos(t), t * Math.Sin(t));
+ //mit lambda?
+ //var p = new Point() => { e * (t *= .1) * System.Math.Cos(t), t* System.Math.Sin(t) };
+ //oder
+ //return (t) => { e * ( t *= .1 ) * Math.cos(t), t * Math.sin(t) };
+ //return function(t) {
+ // return [e * (t *= .1) * Math.Cos(t), t * Math.Sin(t)];
+ //};
+ }
+ //f = afrch(s)
+ //f(t)
+
+ //private System.Windows.Point rectangularSpiral(System.Windows.Size size) {
+ // var dy = 4;
+ // var dx = dy * size.Width / size.Height;
+ // var x = 0;
+ // var y = 0;
+ // return function(t) {
+ // var sign = t < 0 ? -1 : 1;
+ // // See triangular numbers: T_n = n * (n + 1) / 2.
+ // switch ((Math.sqrt(1 + 4 * sign * t) - sign) & 3)
+ // {
+ // case 0: x += dx; break;
+ // case 1: y += dy; break;
+ // case 2: x -= dx; break;
+ // default: y -= dy; break;
+ // }
+ // return [x, y];
+ // };
+ //}
+/* /d3-cloud inspired */
+
+
+ }
}
\ No newline at end of file
diff --git a/WordCloudCalculatorConsoleApplication/Program.cs b/WordCloudCalculatorConsoleApplication/Program.cs
index f9eb3ea..b7cb9ea 100644
--- a/WordCloudCalculatorConsoleApplication/Program.cs
+++ b/WordCloudCalculatorConsoleApplication/Program.cs
@@ -14,43 +14,61 @@ class Program
static void Main(string[] args)
{
- var list = new List
- {
- new DataRow {Text = "Tag1", Weight = 100},
- new DataRow {Text = "Tag2", Weight = 80},
- new DataRow {Text = "Tag3", Weight = 70},
- new DataRow {Text = "Tag4", Weight = 69},
- new DataRow {Text = "Tag5", Weight = 66},
- new DataRow {Text = "Tag6", Weight = 63},
- new DataRow {Text = "Tag7", Weight = 30},
- new DataRow {Text = "Tag8", Weight = 30},
- new DataRow {Text = "Tag9", Weight = 15},
- new DataRow {Text = "Tag14", Weight = 10},
- new DataRow {Text = "Tag10", Weight = 1},
- new DataRow {Text = "Tag11", Weight = 0}
- };
- var calc = new ExtractingWordCloudCalculator();
- //var calc = new ExtractingWordCloudCalculator();
+<<<<<<< HEAD
+=======
+ var list = new List();
+ //{
+ // new DataRow {Text = "Tag1", Weight = 100},
+ // new DataRow {Text = "Tag2", Weight = 80},
+ // new DataRow {Text = "Tag3", Weight = 70},
+ // new DataRow {Text = "Tag4", Weight = 69},
+ // new DataRow {Text = "Tag5", Weight = 66},
+ // new DataRow {Text = "Tag6", Weight = 63},
+ // new DataRow {Text = "Tag7", Weight = 30},
+ // new DataRow {Text = "Tag8", Weight = 30},
+ // new DataRow {Text = "Tag9", Weight = 15},
+ // new DataRow {Text = "Tag14", Weight = 10},
+ // new DataRow {Text = "Tag10", Weight = 1},
+ // new DataRow {Text = "Tag11", Weight = 0}
+ //};
+
+ int max = 3332;
+ Random r = new Random();
+ for (int i = 0; i < max; ++i) {
+ list.Add( new DataRow { Text = "Tag" + i, Weight = (100 / ( max % 123 ) * i + 1 ) } );
+ }
+
+>>>>>>> origin
+ //var calc = new ExtractingWordCloudCalculator();
+ var calc = new ExtractingWordCloudCalculator();
var appearenaceArgs = new WordCloudAppearenceArguments()
{
PanelSize = new Size(Console.WindowWidth, Console.WindowHeight),
- FontSizeRange = new Range(0.0, 15.0),
- OpacityRange = new Range(0.5, 1.0),
- WordMargin = Margin.None,
+ FontSizeRange = new Range(10, 72.0),
+ OpacityRange = new Range(0.24, 1.0),
+ WordMargin = new Margin(0,0,0,0),
WordSizeCalculator = GetTextMetrics
};
var ret = calc.Calculate(appearenaceArgs, list, row => new WeightedWord {Text = row.Text, Weight = row.Weight});
foreach (var c in ret)
- {
- Console.CursorLeft = Convert.ToInt32(c.Position.Left);
- Console.CursorTop = Convert.ToInt32(c.Position.Top);
- Console.ForegroundColor = ConsoleColor.Black + Convert.ToInt32(c.Opacity * 15);
- Console.Write(c.Text);
- }
+ {
+ var lleft = Convert.ToInt32(c.Position.Left + appearenaceArgs.PanelSize.Width / 2);
+ var ltop = Convert.ToInt32(c.Position.Top + appearenaceArgs.PanelSize.Height / 2);
+ var lwidth = lleft + c.Size.Width;
+ var lheight = ltop + c.Size.Height;
+ if (!(lleft < 0 || lleft > appearenaceArgs.PanelSize.Width || lwidth > appearenaceArgs.PanelSize.Width
+ || ltop < 0 || ltop > appearenaceArgs.PanelSize.Height || lheight > appearenaceArgs.PanelSize.Height)) {
+ Console.CursorLeft = lleft;
+ Console.CursorTop = ltop;
+
+ Console.ForegroundColor = (ConsoleColor.Black + 1 + (int)(15 * c.Opacity % 15));
+ Console.Write(c.Text);
+ }
+ }
Console.ReadLine();
}
}
diff --git a/WordCloudCalculatorModule b/WordCloudCalculatorModule
new file mode 160000
index 0000000..b82d346
--- /dev/null
+++ b/WordCloudCalculatorModule
@@ -0,0 +1 @@
+Subproject commit b82d3461f193c9bf15d430ab6180488e95eb6ffd