2017-05-09 2 views
1

Stellen Sie sich vor, ich habe ein Array von Elementen, die aus einer normalisierten Position (t) und einer Breite bestehen.Beste Anpassung für Objekte fester Größe, aber mit normalisierten Positionen

struct Entity 
{ 
    float t;  // left position as a percentage of the parent's size 
    float width; // width of the entity in absolute values 
} 

Sobald ich auf eine Größe für die Eltern entscheiden, kann ich einfach alle Entitäten wie folgt machen:

void Draw(Entity[] entities, float size) 
{ 
    foreach(var entity in entities) 
    { 
     var x = entity.t * size; 
     Draw(x, entity.width);  // x corresponds to left side, not center 
    } 
} 

Ich habe eine harte Zeit, herauszufinden, wie das Minimum zu berechnen size, die es für einen gegebenen Satz von Elementen erlaubt, dass sie gerendert werden, ohne dass ihre Grenzen sich schneiden.


Wenn Sie über den Anwendungsfall für diese neugierig sind, ist es eine Hilfefunktion, die ich brauche ein paar Kanten Fälle auf einem Noten Rendering-System zu lösen. Akkord-Labels werden am Ende des Layout-Zyklus oben auf den Noten platziert, und ihre Positionen müssen richtig mit dem entsprechenden musikalischen Inhalt ausgerichtet sein. Es gibt jedoch Fälle, in denen das Erfüllen dieser Einschränkung bedeutet, dass nicht genügend Platz auf der Kennzahl vorhanden ist, um den Kennzeichnungen zu entsprechen. Ich brauche diese Funktion, um herauszufinden, ob im Voraus nicht genug Platz ist, und wenn nicht, frage das Maß um den fehlenden Betrag.

+0

bekommen Welche Größe Schriftarten verwenden Sie. Sie sollten mit der Größe des Textes beginnen, da Sie die Beschriftungen lesen möchten. – jdweng

Antwort

1

Wenn Sie nicht wollen, die Etiketten dh t sollte immer Position des Etiketts genau linken Ende zu bewegen, ich denke, diese einfache Code tut, was Sie, dass eine minimale Breite

static float CalcMinWidth(IList<Entity> entities) 
    { 
     var count = entities.Count; 
     List<Entity> local = new List<Entity>(count + 1); 
     local.AddRange(entities); 
     local.Add(new Entity(1, 0)); // add one that marks "end" 
     local.Sort((e1, e2) => Comparer<float>.Default.Compare(e1.t, e2.t)); 

     float minReqW = 0; 
     for (int i = 0; i < count; i++) 
     { 
      var e1 = local[i]; 
      var e2 = local[i + 1]; 
      var reqW = e1.width/(e2.t - e1.t); 
      if (reqW > minReqW) 
       minReqW = reqW; 
     } 
     return minReqW; 
    } 

Die Idee ist, brauchen wird durch eine bestimmte Entität e1 angegeben, die sich nicht mit der nächsten Entität e2 überschneiden sollte (oder das Ende, das im Code von einer falschen Entität markiert ist (1.0, 0.0)). Also, was wir haben, ist folgende Gleichung:

e1.t * required_width + e1.width < e2.t * required_width 

Oder wenn Sie es für required_width lösen, die Sie

e1.width/(e2.t - e1.t) < required_width 
+0

Ich habe es noch nicht auf mein Problem angewendet, aber ich habe eine schnelle JS Geige laufen lassen, um es zu testen, und es scheint perfekt zu funktionieren (http://i.imgur.com/HPKhY4J.png). Vielen Dank! –

Verwandte Themen