public PullToTargetPositions(PedigreeModel model) { step = delegate() { foreach (PedigreeIndividual pi in model.individuals) { PedigreeUtils.PullTowardX(model.TargetPositions[pi.HraPerson.relativeID].x, pi.point, 0.1, model); PedigreeUtils.PullTowardY(model.TargetPositions[pi.HraPerson.relativeID].y, pi.point, 0.1, model); } }; }
/*************************************************************************************/ public LayoutSipshipsTwo(PedigreeModel model) { step = delegate() { if (model.individuals.Count < 2) { return; } //if (model.cycles > 150) // return; //for each couple, layout their children foreach (PedigreeCouple parents in model.couples) { parents.children.Sort(delegate(PedigreeIndividual a, PedigreeIndividual b) { double ax = EffectivePosition(a); double bx = EffectivePosition(b); return(ax.CompareTo(bx)); }); double sibWidth = 0; double leftEdge = 0; double rightEdge = 0;; foreach (PedigreeIndividual child in parents.children) { leftEdge = GetLeftEdge(child, double.MaxValue, model); rightEdge = GetRightEdge(child, double.MinValue, model); sibWidth += (rightEdge - leftEdge); } double spacing = sibWidth / ((double)(parents.children.Count)); double i = 0; foreach (PedigreeIndividual child in parents.children) { //position the individuals vertically based on the //positions of the parents: double goalY = parents.point.y + model.parameters.verticalSpacing; double strength = model.parameters.verticalPositioningForceStrength; PedigreeUtils.PullTowardY(goalY, child.point, strength, model); double goalX = leftEdge + (spacing * i); PedigreeUtils.PullTowardX(goalX, child.point, strength, model); i++; } } }; }
public LayoutSibships(PedigreeModel model) { step = delegate() { if (model.individuals.Count < 2) { return; } //if (model.cycles > 150) // return; //for each couple, layout their children foreach (PedigreeCouple parents in model.couples) { PedigreeCouple otherCouple = null; foreach (PedigreeCouple otherparents in model.couples) { if (parents != otherparents && (parents.mother == otherparents.mother || parents.father == otherparents.father)) { if (otherparents.alreadyHandledHalfSibship == false) { otherCouple = otherparents; parents.alreadyHandledHalfSibship = true; double oneleft = double.MaxValue; double oneright = double.MinValue; double twoleft = double.MaxValue; double tworight = double.MinValue; foreach (PedigreeIndividual one in parents.children) { if (one.point.x < oneleft) { oneleft = one.point.x; } if (one.point.x > oneright) { oneright = one.point.x; } } foreach (PedigreeIndividual two in otherparents.children) { if (two.point.x < twoleft) { twoleft = two.point.x; } if (two.point.x > tworight) { tworight = two.point.x; } } foreach (PedigreeIndividual two in otherparents.children) { if (two.point.x < oneright && two.point.x > oneleft) { if (parents.point.x < otherparents.point.x) { PedigreeUtils.PullTowardX(tworight, two.point, 5, model); } else { PedigreeUtils.PullTowardX(oneleft, two.point, 5, model); } } } } } } //Pull children toward their computed ideal locations as follows: //Step 1 of 2: Sort sibship by x position parents.children.Sort(delegate(PedigreeIndividual a, PedigreeIndividual b) { double ax = EffectivePosition(a); double bx = EffectivePosition(b); return(ax.CompareTo(bx)); }); //Step 2 of 2: Pull sibship members toward their ideal positions, //spaced ideally and centered around thir parent couple, leaving //open spaces for spouses (as they will be positioned by the //layout step addressing couples). double spacing; //Compute the offset from the couple center for positioning individuals double offset = 0; int numIndividualsInSibshipSpan = 0; //compute the center for the couple's sibship double sibshipMinX = double.MaxValue; double sibshipMaxX = -double.MaxValue; for (int j = 0; j < parents.children.Count; j++) { PedigreeIndividual child = parents.children[j]; if (child.point.x < sibshipMinX) { sibshipMinX = (int)child.point.x; } if (child.point.x > sibshipMaxX) { sibshipMaxX = (int)child.point.x; } //double leftEdge = GetLeftEdge(child, double.MaxValue, model); //double rightEdge = GetRightEdge(child, double.MinValue, model); //if (leftEdge < sibshipMinX) // sibshipMinX = (int)leftEdge; //if (rightEdge > sibshipMaxX) // sibshipMaxX = (int)rightEdge; //count the child numIndividualsInSibshipSpan++; foreach (PedigreeCouple pc in child.spouseCouples) { //overlap += pc.childOverlap; if (pc.mother != null && pc.father != null) { PedigreeIndividual spouse; if (child.HraPerson.relativeID == pc.mother.HraPerson.relativeID) { spouse = pc.father; } else { spouse = pc.mother; } bool thisSpouseCounts = true; bool spouseIsToRight = spouse.point.x > child.point.x; //don't count the spouse to the right of //the sibship's rightmost child if (j == parents.children.Count - 1 && spouseIsToRight) { thisSpouseCounts = false; } //don't count the spouse to the left of //the sibship's leftmost child if (j == 0 && !spouseIsToRight) { thisSpouseCounts = false; } if (model.parameters.hideNonBloodRelatives && !spouse.bloodRelative) { thisSpouseCounts = false; } if (thisSpouseCounts) { numIndividualsInSibshipSpan++; } } } } double sibshipSpanSize = (sibshipMaxX - sibshipMinX) * model.parameters.sibshipShrinkingFacor; if (numIndividualsInSibshipSpan == 1) { spacing = 0; } else { spacing = (sibshipSpanSize / (numIndividualsInSibshipSpan - 1)); } if (spacing < model.parameters.horizontalSpacing) { spacing = model.parameters.horizontalSpacing; sibshipSpanSize = ((numIndividualsInSibshipSpan - 1) * spacing); } offset = parents.point.x - sibshipSpanSize / 2; //position individuals ideally by applying a force to them int i = 0; foreach (PedigreeIndividual child in parents.children) { //position the individuals vertically based on the //positions of the parents: { double goalY = parents.point.y + model.parameters.verticalSpacing; double strength = model.parameters.verticalPositioningForceStrength; PedigreeUtils.PullTowardY(goalY, child.point, strength, model); } //position the individuals horizontally based on //computation of their ideal horizontal positions { double goalX = offset; //if the child has no spouse if (child.spouseCouples.Count == 0) { //compute the position directly //without incrementing i goalX += i * spacing; } //if the child has a spouse, insert appropriate spacing foreach (PedigreeCouple pc in child.spouseCouples) { if (pc.mother != null && pc.father != null) { PedigreeIndividual spouse; if (child.HraPerson.relativeID == pc.mother.HraPerson.relativeID) { spouse = pc.father; } else { spouse = pc.mother; } if (!model.parameters.hideNonBloodRelatives || spouse.bloodRelative) { bool spouseIsToRight = spouse.point.x > child.point.x; int index = parents.children.IndexOf(child); //if the spouse is to the right... if (spouseIsToRight) { //...but not for the rightmost child if (index != parents.children.Count - 1) { //leave a space to the right. goalX = offset + (i++) * spacing; } else { goalX = offset + i * spacing; } } else//if the spouse is to the left... //...but not for the leftmost child if (index != 0) { //leave a space to the left. goalX = offset + (++i) * spacing; } } else { goalX += i * (spacing); } } } double strength = model.parameters.layoutSibshipsStrength; PedigreeUtils.PullTowardX(goalX, child.point, strength, model); //increment i to account for enumeration this child i++; } } } }; }
public PullTowardIdealVerticalPositions(PedigreeModel model) { step = delegate() { if (model.individuals.Count < 2) { return; } double spacing = model.parameters.verticalSpacing; double centerY = (model.displayYMin + model.displayYMax) / 2; double offset = centerY - (model.maxGenerationalLevel + 1) * spacing / 2; foreach (PedigreeCouple couple in model.couples) { //pull the couples toward their optimal positions //based on their generational level int level = couple.GenerationalLevel; if (level >= 0) { double goalY = level * spacing + offset; double strength = model.parameters.verticalPositioningForceStrength; PedigreeUtils.PullTowardY(goalY, couple.point, strength, model); //position the individuals vertically based on the //positions of the couples: goalY = couple.point.y; strength = model.parameters.verticalPositioningForceStrength; if (couple.mother != null) { if (model.pointsBeingDragged.Contains(couple.mother.point) == false) { PedigreeUtils.PullTowardY(goalY, couple.mother.point, strength, model); //foreach (PedigreeCouple pc in couple.mother.spouseCouples) //{ // PedigreeUtils.PullTowardY(goalY, pc.father.point, strength, model); //} } } if (couple.father != null) { if (model.pointsBeingDragged.Contains(couple.father.point) == false) { PedigreeUtils.PullTowardY(goalY, couple.father.point, strength, model); //foreach (PedigreeCouple pc in couple.father.spouseCouples) //{ // PedigreeUtils.PullTowardY(goalY, pc.mother.point, strength, model); //} } } foreach (PedigreeIndividual pi in couple.children) { if (model.pointsBeingDragged.Contains(pi.point) == false) { if ((couple.mother != null) && (couple.father != null)) { double target = ((couple.mother.point.y + couple.father.point.y) / 2) + (model.parameters.verticalSpacing); pi.point.y = target; PedigreeUtils.PullTowardY(target, pi.point, model.parameters.verticalPositioningForceStrength, model); } } } } } }; }