예제 #1
0
 public IncrementControllerVariables(PedigreeModel model, PedigreeController layoutEngine)
 {
     step = delegate()
     {
         model.parameters.ControllerMode = layoutEngine.GetMode();
     };
 }
예제 #2
0
        public LayoutHoldingPen(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                //pull everything gently toward the center horizontally
                int minX = int.MaxValue;
                int maxX = -minX;

                foreach (PedigreeIndividual pi in model.individuals)
                {
                    if (model.HoldingPen.ContainsKey(pi.HraPerson.relativeID) == false)
                    {
                        if (pi.point.x < minX)
                            minX = (int)pi.point.x;
                    }
                }
                model.parameters.HoldingPenOrigin.X = minX;
                int count = 0;
                foreach (PedigreeIndividual pi in model.HoldingPen.Values)
                {
                        pi.point.x = model.parameters.HoldingPenOrigin.X + (model.parameters.horizontalSpacing * count);
                        pi.point.y = model.parameters.HoldingPenOrigin.Y + (model.parameters.verticalSpacing / 2);
                        count++;
                }
            };
        }
예제 #3
0
 public AutoSave(PedigreeModel model, PedigreeController layoutEngine)
 {
     step = delegate()
     {
         layoutEngine.Finished();
     };
 }
예제 #4
0
 public IncrementControllerVariables(PedigreeModel model, PedigreeController layoutEngine)
 {
     step = delegate()
     {
         model.parameters.ControllerMode = layoutEngine.GetMode();
     };
 }
예제 #5
0
        public LayoutHoldingPen(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                //pull everything gently toward the center horizontally
                int minX = int.MaxValue;
                int maxX = -minX;

                foreach (PedigreeIndividual pi in model.individuals)
                {
                    if (model.HoldingPen.ContainsKey(pi.HraPerson.relativeID) == false)
                    {
                        if (pi.point.x < minX)
                        {
                            minX = (int)pi.point.x;
                        }
                    }
                }
                model.parameters.HoldingPenOrigin.X = minX;
                int count = 0;
                foreach (PedigreeIndividual pi in model.HoldingPen.Values)
                {
                    pi.point.x = model.parameters.HoldingPenOrigin.X + (model.parameters.horizontalSpacing * count);
                    pi.point.y = model.parameters.HoldingPenOrigin.Y + (model.parameters.verticalSpacing / 2);
                    count++;
                }
            };
        }
        public LevelRestrictedForceDirectedLayout(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                if (!model.couplesGraphIsPlanar)
                {
                    attractAdjacentCouplePairs(model);
                    repelAllCouplePairs(model);


                    //int n = model.coupleEdges.Count;
                    //for (int i = 0; i < n; i++)
                    //    for (int j = i + 1; j < n; j++)
                    //        if (model.edgesCross(model.coupleEdges[i], model.coupleEdges[j]))
                    //        {
                    //            ShrinkEdge(model.coupleEdges[i]);
                    //            ShrinkEdge(model.coupleEdges[j]);
                    //        }
                }
            };
        }
예제 #7
0
 /// <summary>
 /// Adds a layout step to this layout engine.
 /// </summary>
 public void AddLayoutStep(String mode, LayoutStep layoutStep)
 {
     if (!layoutSteps.ContainsKey(mode))
     {
         layoutSteps.Add(mode, new List <LayoutStep>());
     }
     layoutSteps[mode].Add(layoutStep);
 }
예제 #8
0
파일: AutoSave.cs 프로젝트: mahitosh/HRA4
        public AutoSave(PedigreeModel model, PedigreeController layoutEngine)
        {
            step = delegate()
            {

                layoutEngine.Finished();

            };
        }
예제 #9
0
파일: SwapSibs.cs 프로젝트: mahitosh/HRA4
        public SwapSibs(PedigreeModel model)
        {
            step = delegate()
            {
                foreach (PedigreeCouple pc1 in model.couples)
                {
                    pc1.point.x = (pc1.mother.point.x + pc1.father.point.x) / 2;
                    pc1.point.y = (pc1.mother.point.y + pc1.father.point.y) / 2;

                    foreach (PedigreeCouple pc2 in model.couples)
                    {
                        pc2.point.x = (pc2.mother.point.x + pc2.father.point.x) / 2;
                        pc2.point.y = (pc2.mother.point.y + pc2.father.point.y) / 2;

                        if (pc1 != pc2)
                        {
                            if (Math.Abs(pc1.point.y - pc2.point.y) < (model.parameters.verticalSpacing / 2))
                            {
                                bool FirstIsLeft = false;
                                if (pc1.point.x < pc2.point.x)
                                {
                                    FirstIsLeft = true;
                                }

                                foreach (PedigreeIndividual pi1 in pc1.children)
                                {
                                    foreach (PedigreeIndividual pi2 in pc2.children)
                                    {
                                        if (FirstIsLeft)
                                        {
                                            if (pi2.point.x < pi1.point.x)
                                            {
                                                double temp = pi2.point.x;
                                                pi2.point.x = pi1.point.x;
                                                pi1.point.x = temp;
                                                return;
                                            }
                                        }
                                        else
                                        {
                                            if (pi1.point.x < pi2.point.x)
                                            {
                                                double temp = pi2.point.x;
                                                pi2.point.x = pi1.point.x;
                                                pi1.point.x = temp;
                                                return;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };
        }
예제 #10
0
        public DetectPlanarity(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                model.couplesGraphIsPlanar = CouplesGraphIsPlanar(model);
            };
        }
예제 #11
0
        public DetectValidLayout(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                model.layoutIsValid = LayoutIsValid(model);
            };
        }
예제 #12
0
 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);
         }
     };
 }
예제 #13
0
 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);
         }
     };
 }
예제 #14
0
        public ComputeCenters(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                if (model.couplesGraphIsPlanar)
                {
                    foreach (PedigreeCouple couple in model.couples)
                    {
                        if (!model.pointsBeingDragged.Contains(couple.point))
                        {
                            //compute the center for the couple
                            if (couple.mother != null && couple.father != null)
                            {
                                double motherX       = couple.mother.point.x;
                                double motherY       = couple.mother.point.y + model.parameters.individualSize / 2;
                                double fatherX       = couple.father.point.x;
                                double fatherY       = couple.father.point.y + model.parameters.individualSize / 2;
                                double coupleCenterX = (motherX + fatherX) / 2;

                                //compute the center for the couple's sibship
                                double sibshipMinX = double.MaxValue;
                                double sibshipMaxX = -double.MaxValue;
                                foreach (PedigreeIndividual child in couple.children)
                                {
                                    if (child.point.x < sibshipMinX)
                                    {
                                        sibshipMinX = (int)child.point.x;
                                    }
                                    if (child.point.x > sibshipMaxX)
                                    {
                                        sibshipMaxX = (int)child.point.x;
                                    }
                                }

                                double sibshipY = couple.point.y +
                                                  model.parameters.verticalSpacing - model.parameters.individualSize / 2;
                                double sibshipCenterX = (sibshipMinX + sibshipMaxX) / 2;

                                //this is the middle point between parents and children from which
                                //ideal positions of both are derived
                                double middleX = (sibshipCenterX + coupleCenterX) / 2;
                                couple.point.x = middleX;
                            }
                        }
                    }
                }
            };
        }
예제 #15
0
        public IncrementIOVariables(PedigreeModel model)
        {
            step = delegate()
            {
                model.io.mousePressed = !model.io.pMouseDown && model.io.mouseDown;
                model.io.mouseReleased = model.io.pMouseDown && !model.io.mouseDown;

                model.io.pMouseDown = model.io.mouseDown;
                model.io.pMouseX = model.io.mouseX;
                model.io.pMouseY = model.io.mouseY;
            };
        }
예제 #16
0
        public DetectValidLayout(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                model.layoutIsValid = LayoutIsValid(model);
            };
        }
예제 #17
0
        public IncrementIOVariables(PedigreeModel model)
        {
            step = delegate()
            {
                model.io.mousePressed  = !model.io.pMouseDown && model.io.mouseDown;
                model.io.mouseReleased = model.io.pMouseDown && !model.io.mouseDown;

                model.io.pMouseDown = model.io.mouseDown;
                model.io.pMouseX    = model.io.mouseX;
                model.io.pMouseY    = model.io.mouseY;
            };
        }
예제 #18
0
        public DetectPlanarity(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                model.couplesGraphIsPlanar = CouplesGraphIsPlanar(model);
            };
        }
예제 #19
0
        /*************************************************************************************/
        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++;
                    }
                }
            };
        }
예제 #20
0
        /*************************************************************************************/
        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++;
                    }
                }
            };
        }
예제 #21
0
        public DragPoints(PedigreeModel model, PedigreeController layoutEngine)
        {
            step = delegate()
            {
                //if the mouse was pressed and there were no couples being dragged,
                //drag the one under the mouse point.
                if (model.io.mousePressed)
                {
                    double            x = model.io.mouseX; // -model.parameters.hOffset;
                    double            y = model.io.mouseY; // -model.parameters.vOffset;
                    PointWithVelocity pointUnderCursor = GetPointUnderCursor(model, x, y);

                    if (model.Selected.Count < 2)
                    {
                        if (pointUnderCursor != null)
                        {
                            model.pointsBeingDragged.Add(pointUnderCursor);
                        }
                    }
                    else
                    {
                        bool found = false;
                        foreach (PedigreeIndividual pi in model.Selected)
                        {
                            model.pointsBeingDragged.Add(pi.point);
                            if (pi.point == pointUnderCursor)
                            {
                                found = true;
                            }
                        }
                        if (found == false)
                        {
                            model.pointsBeingDragged.Clear();
                        }
                    }
                }
                if (model.io.mouseReleased)
                {
                    model.pointsBeingDragged.Clear();
                }

                foreach (PointWithVelocity point in model.pointsBeingDragged)
                {
                    point.x += ((model.io.mouseX - model.io.pMouseX) / model.parameters.scale);
                    point.y += ((model.io.mouseY - model.io.pMouseY) / model.parameters.scale);
                }
            };
        }
예제 #22
0
        public ComputeCenters(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                if (model.couplesGraphIsPlanar)
                {
                    foreach (PedigreeCouple couple in model.couples)
                    {
                        if (!model.pointsBeingDragged.Contains(couple.point))
                        {
                            //compute the center for the couple
                            if (couple.mother != null && couple.father != null)
                            {
                                double motherX = couple.mother.point.x;
                                double motherY = couple.mother.point.y + model.parameters.individualSize / 2;
                                double fatherX = couple.father.point.x;
                                double fatherY = couple.father.point.y + model.parameters.individualSize / 2;
                                double coupleCenterX = (motherX + fatherX) / 2;

                                //compute the center for the couple's sibship
                                double sibshipMinX = double.MaxValue;
                                double sibshipMaxX = -double.MaxValue;
                                foreach (PedigreeIndividual child in couple.children)
                                {
                                    if (child.point.x < sibshipMinX)
                                        sibshipMinX = (int)child.point.x;
                                    if (child.point.x > sibshipMaxX)
                                        sibshipMaxX = (int)child.point.x;
                                }

                                double sibshipY = couple.point.y +
                                    model.parameters.verticalSpacing - model.parameters.individualSize / 2;
                                double sibshipCenterX = (sibshipMinX + sibshipMaxX) / 2;

                                //this is the middle point between parents and children from which
                                //ideal positions of both are derived
                                double middleX = (sibshipCenterX + coupleCenterX) / 2;
                                couple.point.x = middleX;
                            }
                        }
                    }
                }
            };
        }
예제 #23
0
파일: DragPoints.cs 프로젝트: mahitosh/HRA4
        public DragPoints(PedigreeModel model, PedigreeController layoutEngine)
        {
            step = delegate()
            {
                //if the mouse was pressed and there were no couples being dragged,
                //drag the one under the mouse point.
                if (model.io.mousePressed)
                {
                    double x = model.io.mouseX;// -model.parameters.hOffset;
                    double y = model.io.mouseY;// -model.parameters.vOffset;
                    PointWithVelocity pointUnderCursor = GetPointUnderCursor(model, x, y);

                    if (model.Selected.Count < 2)
                    {
                        if (pointUnderCursor != null)
                            model.pointsBeingDragged.Add(pointUnderCursor);
                    }
                    else
                    {
                        bool found = false;
                        foreach (PedigreeIndividual pi in model.Selected)
                        {
                            model.pointsBeingDragged.Add(pi.point);
                            if (pi.point == pointUnderCursor)
                            {
                                found = true;
                            }
                        }
                        if (found == false)
                        {
                            model.pointsBeingDragged.Clear();
                        }
                    }
                }
                if (model.io.mouseReleased)
                {
                    model.pointsBeingDragged.Clear();
                }

                foreach (PointWithVelocity point in model.pointsBeingDragged)
                {
                    point.x += ((model.io.mouseX - model.io.pMouseX) / model.parameters.scale);
                    point.y += ((model.io.mouseY - model.io.pMouseY) / model.parameters.scale);
                }
            };
        }
예제 #24
0
        public PullTowardCenterHorizontally(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                //pull everything gently toward the center horizontally
                //foreach (PointWithVelocity point in model.points)
                //{
                //    double goalX = (model.displayXMin + model.displayXMax) / 2;
                //    double strength = model.parameters.centeringForceStrength;
                //    //strength = 0.06;
                //    PedigreeUtils.PullTowardX(goalX, point,strength);
                //}

                //pull everything gently toward the center horizontally
                double minX = double.MaxValue;
                double maxX = -minX;

                foreach (PointWithVelocity point in model.points)
                {
                    if (point.x < minX)
                    {
                        minX = point.x;
                    }
                    else if (point.x > maxX)
                    {
                        maxX = point.x;
                    }
                }

                double centerX      = (minX + maxX) / 2;
                double idealCenterX = (model.displayXMin + model.displayXMax) / 2;
                double offset       = idealCenterX - centerX;
                foreach (PointWithVelocity point in model.points)
                {
                    double goalX    = point.x + offset;
                    double strength = model.parameters.centeringForceStrength;
                    PedigreeUtils.PullTowardX(goalX, point, strength, model);
                }
            };
        }
예제 #25
0
 public IncrementVelocities(PedigreeModel model)
 {
     step = delegate()
     {
         foreach (PointWithVelocity point in model.points)
         {
             if (!model.pointsBeingDragged.Contains(point))
             {
                 point.x += point.dx;
                 point.y += point.dy;
                 point.dx *= model.parameters.dampeningFactor;
                 point.dy *= model.parameters.dampeningFactor;
             }
             else
                 point.dx = point.dy = 0;
         }
     };
 }
예제 #26
0
        public PlaceIndividualsOverCouples(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                if(!model.couplesGraphIsPlanar)
                    foreach (PedigreeCouple couple in model.couples)
                    {
                        couple.mother.point.Set(couple.point);
                        couple.father.point.Set(couple.point);
                        foreach(PedigreeIndividual child in couple.children)
                            child.point.Set(couple.point);

                    }
            };
        }
예제 #27
0
 public EllapsedTimeCheck(PedigreeModel model)
 {
     step = delegate()
     {
         model.cycles++;
         if (model.cycles % 200 == 0 && model.cycles <= 800 && model.layoutIsValid == false)
         {
             foreach (PointWithVelocity p in model.points)
             {
                 double newX = autoRand.NextDouble() * (model.displayXMax - 1);
                 double newY = autoRand.NextDouble() * (model.displayYMax - 1);
                 p.x  = newX;
                 p.dx = 0;
                 p.y  = newY;
                 p.dy = 0;
             }
         }
     };
 }
예제 #28
0
 public IncrementVelocities(PedigreeModel model)
 {
     step = delegate()
     {
         foreach (PointWithVelocity point in model.points)
         {
             if (!model.pointsBeingDragged.Contains(point))
             {
                 point.x  += point.dx;
                 point.y  += point.dy;
                 point.dx *= model.parameters.dampeningFactor;
                 point.dy *= model.parameters.dampeningFactor;
             }
             else
             {
                 point.dx = point.dy = 0;
             }
         }
     };
 }
예제 #29
0
파일: SnapToGrid.cs 프로젝트: mahitosh/HRA4
        public SnapToGrid(PedigreeModel model, PedigreeController layoutEngine)
        {
            step = delegate()
            {
                if (model.io.mousePressed == false)
                {
                    foreach (PedigreeIndividual pi in model.individuals)
                    {
                        if (model.pointsBeingDragged.Contains(pi.point) == false)
                        {
                            double deltaX = pi.point.x % model.parameters.gridWidth;
                            if (deltaX > 0.0)
                            {
                                if (deltaX >= (model.parameters.gridWidth / 2.0))
                                {
                                    pi.point.x += (model.parameters.gridWidth - deltaX);
                                }
                                else
                                {
                                    pi.point.x -= (deltaX);
                                }
                            }

                            double deltaY = pi.point.y % model.parameters.gridHeight;
                            if (deltaY > 0.0)
                            {
                                if (deltaY >= (model.parameters.gridHeight / 2.0))
                                {
                                    pi.point.y += (model.parameters.gridHeight - deltaY);
                                }
                                else
                                {
                                    pi.point.y -= (deltaY);
                                }
                            }
                        }
                    }
                }
            };
        }
예제 #30
0
        public EllapsedTimeCheck(PedigreeModel model)
        {
            step = delegate()
            {
                model.cycles++;
                if (model.cycles % 200 == 0 && model.cycles <= 800 && model.layoutIsValid == false)
                {
                    foreach (PointWithVelocity p in model.points)
                    {
                        double newX = autoRand.NextDouble() * (model.displayXMax - 1);
                        double newY = autoRand.NextDouble() * (model.displayYMax - 1);
                        p.x = newX;
                        p.dx = 0;
                        p.y = newY;
                        p.dy = 0;

                    }

                }

            };
        }
예제 #31
0
        public PlaceIndividualsOverCouples(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                if (!model.couplesGraphIsPlanar)
                {
                    foreach (PedigreeCouple couple in model.couples)
                    {
                        couple.mother.point.Set(couple.point);
                        couple.father.point.Set(couple.point);
                        foreach (PedigreeIndividual child in couple.children)
                        {
                            child.point.Set(couple.point);
                        }
                    }
                }
            };
        }
예제 #32
0
        public PullTowardCenterHorizontally(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                //pull everything gently toward the center horizontally
                //foreach (PointWithVelocity point in model.points)
                //{
                //    double goalX = (model.displayXMin + model.displayXMax) / 2;
                //    double strength = model.parameters.centeringForceStrength;
                //    //strength = 0.06;
                //    PedigreeUtils.PullTowardX(goalX, point,strength);
                //}

                //pull everything gently toward the center horizontally
                double minX = double.MaxValue;
                double maxX = -minX;

                foreach (PointWithVelocity point in model.points)
                    if (point.x < minX)
                        minX = point.x;
                    else if (point.x > maxX)
                        maxX = point.x;

                double centerX = (minX + maxX) / 2;
                double idealCenterX = (model.displayXMin + model.displayXMax) / 2;
                double offset = idealCenterX - centerX;
                foreach (PointWithVelocity point in model.points)
                {
                    double goalX = point.x + offset;
                    double strength = model.parameters.centeringForceStrength;
                    PedigreeUtils.PullTowardX(goalX, point, strength, model);
                }
            };
        }
        public LevelRestrictedForceDirectedLayout(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                if (!model.couplesGraphIsPlanar)
                {
                    attractAdjacentCouplePairs(model);
                    repelAllCouplePairs(model);

                    //int n = model.coupleEdges.Count;
                    //for (int i = 0; i < n; i++)
                    //    for (int j = i + 1; j < n; j++)
                    //        if (model.edgesCross(model.coupleEdges[i], model.coupleEdges[j]))
                    //        {
                    //            ShrinkEdge(model.coupleEdges[i]);
                    //            ShrinkEdge(model.coupleEdges[j]);
                    //        }

                }
            };
        }
예제 #34
0
        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);
                                }
                            }
                        }
                    }
                }
            };
        }
예제 #36
0
 /// <summary>
 /// Adds a layout step to this layout engine.
 /// </summary>
 public void AddLayoutStep(String mode,LayoutStep layoutStep)
 {
     if (!layoutSteps.ContainsKey(mode))
         layoutSteps.Add(mode, new List<LayoutStep>());
     layoutSteps[mode].Add(layoutStep);
 }
        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);
                                }
                            }

                        }
                    }
                }
            };
        }
예제 #38
0
        public AttractCouples(PedigreeModel model)
        {
            step = delegate()
            {
                foreach (PedigreeCouple pc in model.couples)
                {
                    if ((pc.mother != null) && (pc.father != null))
                    {
                        if (pc.mother.Mother != null &&
                            pc.mother.Father != null &&
                            pc.father.Mother != null &&
                            pc.father.Father != null)
                        {
                            double motherAvgX = (pc.mother.Mother.point.x + pc.mother.Father.point.x) / 2;
                            double fatherAvgX = (pc.father.Mother.point.x + pc.father.Father.point.x) / 2;

                            if (pc.mother.point.x > pc.father.point.x && motherAvgX < fatherAvgX)
                            {
                                double temp = pc.mother.point.x;
                                pc.mother.point.x = pc.father.point.x;
                                pc.father.point.x = temp;
                            }
                            else if (pc.father.point.x > pc.mother.point.x && fatherAvgX < motherAvgX)
                            {
                                double temp = pc.mother.point.x;
                                pc.mother.point.x = pc.father.point.x;
                                pc.father.point.x = temp;
                            }
                        }

                        if (pc.children.Count > 0)
                        {
                            double xAcc = 0;
                            double yAcc = 0;
                            double sibMin = double.MaxValue;
                            double sibMax = double.MinValue;
                            foreach (PedigreeIndividual kid in pc.children)
                            {
                                xAcc += kid.point.x;
                                yAcc += kid.point.y;
                                if (sibMin > kid.point.x)
                                    sibMin = kid.point.x;
                                if (sibMax < kid.point.x)
                                    sibMax = kid.point.x;
                            }
                            xAcc = (sibMin + sibMax) / 2;
                            yAcc /= (double)pc.children.Count;

                            double distance = Math.Abs(pc.mother.point.x - pc.father.point.x);
                            double coupleAvg = (pc.mother.point.x + pc.father.point.x) / (2.0);

                            if (!model.parameters.hideNonBloodRelatives || (pc.mother.bloodRelative && pc.father.bloodRelative))
                            {
                                if (pc.mother.point.x < pc.father.point.x)
                                {
                                    PedigreeUtils.PullTowardX(xAcc - (distance / 2), pc.mother.point, 0.1, model);
                                    PedigreeUtils.PullTowardX(xAcc + (distance / 2), pc.father.point, 0.1, model);
                                }
                                else
                                {
                                    PedigreeUtils.PullTowardX(xAcc + (distance / 2), pc.mother.point, 0.1, model);
                                    PedigreeUtils.PullTowardX(xAcc - (distance / 2), pc.father.point, 0.1, model);
                                }

                                List<PedigreeIndividual> kidsPulledToParents = new List<PedigreeIndividual>();
                                if (Math.Abs(pc.mother.point.x - pc.father.point.x) < (0.90 * model.parameters.horizontalSpacing))
                                {
                                    SeperateCouple(pc, model, xAcc, ref kidsPulledToParents);
                                }
                            }
                            else
                            {
                                if (model.parameters.hideNonBloodRelatives)
                                {
                                    if (pc.mother.bloodRelative && !pc.father.bloodRelative)
                                    {
                                        PedigreeUtils.PullTowardX(pc.mother.point.x, pc.father.point, 0.1, model);
                                    }
                                    else if (!pc.mother.bloodRelative && pc.father.bloodRelative)
                                    {
                                        PedigreeUtils.PullTowardX(pc.father.point.x, pc.mother.point, 0.1, model);
                                    }
                                }

                                pc.mother.point.x = coupleAvg;
                                pc.father.point.x = coupleAvg;
                            }
                        }
                    }
                }
            };
        }
예제 #39
0
        public CenterParents(PedigreeModel model)
        {
            step = delegate()
            {
                ////initialize the per-level ordering lists for each generation
                //for (int generationIndex = 0; generationIndex <= model.maxGenerationalLevel + 1; generationIndex++)
                //{

                //    List<PedigreeIndividual> generation = PedigreeUtils.GetIndividualsInGeneration(model, generationIndex);
                //    for (int i = 0; i < generation.Count; i++)
                //    {

                //    }
                //}
            };
            //if (model.couplesGraphIsPlanar)
            //{
            //    foreach (PedigreeCouple couple in model.couples)
            //    {

            //        if (!model.pointsBeingDragged.Contains(couple.point))
            //        {
            //            //compute the center for the couple
            //            double motherX = couple.mother.point.x;
            //            double motherY = couple.mother.point.y + model.parameters.individualSize / 2;
            //            double fatherX = couple.father.point.x;
            //            double fatherY = couple.father.point.y + model.parameters.individualSize / 2;
            //            double coupleCenterX = (motherX + fatherX) / 2;


            //            //compute the center for the couple's sibship
            //            double sibshipMinX = double.MaxValue;
            //            double sibshipMaxX = -double.MaxValue;
            //            foreach (PedigreeIndividual child in couple.children)
            //            {
            //                if (child.point.x < sibshipMinX)
            //                    sibshipMinX = (int)child.point.x;
            //                if (child.point.x > sibshipMaxX)
            //                    sibshipMaxX = (int)child.point.x;
            //            }

            //            double sibshipY = couple.point.y +
            //                model.parameters.verticalSpacing - model.parameters.individualSize / 2;
            //            double sibshipCenterX = (sibshipMinX + sibshipMaxX) / 2;

            //            //this is the middle point between parents and children from which
            //            //ideal positions of both are derived
            //            //double middleX = (sibshipCenterX + coupleCenterX) / 2;
            //            if (couple.mother.point.x < couple.father.point.x)
            //            {
            //                PedigreeUtils.PullTowardX(sibshipCenterX + (model.parameters.horizontalSpacing / 2), couple.mother.point, 2, model);
            //                PedigreeUtils.PullTowardX(sibshipCenterX - (model.parameters.horizontalSpacing / 2), couple.father.point, 2, model);
            //            }
            //            else
            //            {
            //                PedigreeUtils.PullTowardX(sibshipCenterX + (model.parameters.horizontalSpacing / 2), couple.mother.point, 2, model);
            //                PedigreeUtils.PullTowardX(sibshipCenterX - (model.parameters.horizontalSpacing / 2), couple.father.point, 2, model);
            //            }
            //             /**/
            //        }


            //        //if (Math.Abs(couple.mother.point.x - couple.father.point.x) > 120)
            //        //{
            //        //    if (couple.mother.point.x < couple.father.point.x)
            //        //    {
            //        //        PedigreeUtils.PullTowardX(couple.father.point.x + 60, couple.mother.point, 0.25, model);
            //        //        PedigreeUtils.PullTowardX(couple.mother.point.x - 60, couple.father.point, 0.25, model);
            //        //    }
            //        //    else
            //        //    {
            //        //        PedigreeUtils.PullTowardX(couple.father.point.x - 60, couple.mother.point, 0.25, model);
            //        //        PedigreeUtils.PullTowardX(couple.mother.point.x + 60, couple.father.point, 0.25, model);
            //        //    }
            //        //}
            //    }
            //}
            /* */

            /*
             * //initialize the per-level ordering lists for each generation
             * for (int generationIndex = 0; generationIndex <= model.maxGenerationalLevel + 1; generationIndex++)
             * {
             *
             *  List<PedigreeIndividual> generation = PedigreeUtils.GetIndividualsInGeneration(model, generationIndex);
             *  for (int i = 0; i < generation.Count; i++)
             *  {
             *      for (int j = i; j < generation.Count; j++)
             *      {
             *          PedigreeIndividual one = generation[i];
             *          PedigreeIndividual two = generation[j];
             *          double delta = Math.Abs(one.point.x - two.point.x);
             *          if ( delta < (model.parameters.horizontalSpacing))
             *          {
             *              if (one.Parents.point.x < two.Parents.point.x)
             *              {
             *                  PedigreeUtils.PullTowardX(one.point.x - (model.parameters.horizontalSpacing - delta), one.point, 1, model);
             *                  PedigreeUtils.PullTowardX(two.point.x + (model.parameters.horizontalSpacing - delta), two.point, 1, model);
             *              }
             *              else
             *              {
             *                  PedigreeUtils.PullTowardX(one.point.x + (model.parameters.horizontalSpacing - delta), one.point, 1, model);
             *                  PedigreeUtils.PullTowardX(two.point.x - (model.parameters.horizontalSpacing - delta), two.point, 1, model);
             *              }
             *          }
             *
             *      }
             *  }
             * }
             *
             * if (model.couplesGraphIsPlanar)
             * {
             *  foreach (PedigreeCouple couple in model.couples)
             *  {
             *
             *      if (!model.pointsBeingDragged.Contains(couple.point))
             *      {
             *          if (Math.Abs(couple.mother.point.x - couple.father.point.x) > (2 * model.parameters.horizontalSpacing))
             *          {
             *
             *              //compute the center for the couple
             *              double motherX = couple.mother.point.x;
             *              double motherY = couple.mother.point.y + model.parameters.individualSize / 2;
             *              double fatherX = couple.father.point.x;
             *              double fatherY = couple.father.point.y + model.parameters.individualSize / 2;
             *              double coupleCenterX = (motherX + fatherX) / 2;
             *
             *              if (couple.mother.point.x < couple.father.point.x)
             *              {
             *                  PedigreeUtils.PullTowardX(coupleCenterX + model.parameters.horizontalSpacing, couple.mother.point, 1, model);
             *                  PedigreeUtils.PullTowardX(coupleCenterX - model.parameters.horizontalSpacing, couple.father.point, 1, model);
             *              }
             *              else
             *              {
             *                  PedigreeUtils.PullTowardX(coupleCenterX - model.parameters.horizontalSpacing, couple.mother.point, 1, model);
             *                  PedigreeUtils.PullTowardX(coupleCenterX + model.parameters.horizontalSpacing, couple.father.point, 1, model);
             *              }
             *          }
             *      }
             *  }
             * }
             */
        }
예제 #40
0
        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++;
                        }
                    }
                }
            };
        }
예제 #41
0
        public RepelIndividuals(PedigreeModel model)
        {
            step = delegate()
            {
                foreach (PedigreeIndividual pi in model.individuals)
                {
                    foreach (PedigreeIndividual neighbor in model.individuals)
                    {
                        if (pi != neighbor)
                        {
                            if (Math.Abs(neighbor.point.y - pi.point.y) < (model.parameters.verticalSpacing / 2))
                            {
                                if (Math.Abs(neighbor.point.x - pi.point.x) < model.parameters.horizontalSpacing)
                                {
                                    if (!model.parameters.hideNonBloodRelatives || (neighbor.bloodRelative && pi.bloodRelative))
                                    {
                                        if (pi.Group == null || pi.Group.Contains(neighbor)==false)
                                        {
                                            if (neighbor.point.x < pi.point.x)
                                            {
                                                PedigreeUtils.PullTowardX(neighbor.point.x + model.parameters.horizontalSpacing, pi.point, model.parameters.repelIndividualSetsStrength, model);
                                            }
                                            else
                                            {
                                                PedigreeUtils.PullTowardX(neighbor.point.x - model.parameters.horizontalSpacing, pi.point, model.parameters.repelIndividualSetsStrength, model);
                                            }
                                        }
                                    }
                                }

                                //check for neighnor placed between person and spouse
                                if (neighbor.HraPerson.motherID == pi.HraPerson.motherID || neighbor.HraPerson.fatherID == pi.HraPerson.fatherID)
                                {
                                    foreach (PedigreeCouple pc in pi.spouseCouples)
                                    {
                                        PedigreeIndividual spouse;
                                        if (pc.mother == pi)
                                            spouse = pc.father;
                                        else
                                            spouse = pc.mother;

                                        if (spouse != null)
                                        {
                                            if (neighbor.point.x > Math.Min(pi.point.x, spouse.point.x) && neighbor.point.x < Math.Max(pi.point.x, spouse.point.x))
                                            {
                                                double x = neighbor.point.x;
                                                neighbor.point.x = pi.point.x;
                                                pi.point.x = x;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };
        }
예제 #42
0
        public LayoutCouples(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                double hSpacing     = model.parameters.horizontalSpacing;
                double halfHSpacing = hSpacing / 2;

                //for each couple, layout the mothers and fathers with no parents
                foreach (PedigreeCouple couple in model.couples)
                {
                    if (model.parameters.hideNonBloodRelatives && couple.mother.bloodRelative && !couple.father.bloodRelative)
                    {
                        couple.father.point.x = couple.mother.point.x;
                        couple.point.x        = couple.mother.point.x;
                    }
                    else if (model.parameters.hideNonBloodRelatives && couple.father.bloodRelative && !couple.mother.bloodRelative)
                    {
                        couple.mother.point.x = couple.father.point.x;
                        couple.point.x        = couple.father.point.x;
                    }
                    else
                    {
                        if (couple.mother != null && couple.father != null)
                        {
                            bool motherHasParents = couple.mother.Parents != null;
                            bool fatherHasParents = couple.father.Parents != null;

                            //if mother and father both have parents,
                            if (motherHasParents && fatherHasParents)
                            {
                                bool fatherToLeft = couple.father.Parents.point.x < couple.mother.Parents.point.x;
                                pullParents(model, couple, fatherToLeft);
                            }
                            //if the mother has parents but the father doesn't,
                            else if (motherHasParents && !fatherHasParents)
                            {
                                //then the mother will be pulled into position by
                                //the layout step for her sibship, so position the
                                //father depending on where the mother is:

                                //pull the father to the left of the mother
                                double            goalX    = couple.mother.point.x - hSpacing;
                                PointWithVelocity point    = couple.father.point;
                                double            strength = model.parameters.layoutCouplesStrength;
                                PedigreeUtils.PullTowardX(goalX, point, strength, model);
                            }
                            //if the father has parents but the mother diesn't,
                            else if (!motherHasParents && fatherHasParents)
                            {
                                //then the father will be pulled into position by
                                //the layout step for his sibship, so position the
                                //mother depending on where the father is:

                                //pull the mother to the right of the father
                                double            goalX    = couple.father.point.x + hSpacing;
                                PointWithVelocity point    = couple.mother.point;
                                double            strength = model.parameters.layoutCouplesStrength;
                                PedigreeUtils.PullTowardX(goalX, point, strength, model);
                            }
                            //if neither the father nor the mother has parents,
                            else if (!motherHasParents && !fatherHasParents)
                            {
                                //then position them according to their spouse position,
                                //placing the father on the left:
                                {
                                    //handle the case of half siblings:
                                    bool coupleIsReversed = false;
                                    if (couple.mother.spouseCouples.Count == 2)
                                    {
                                        PedigreeCouple oppositeCouple;
                                        if (couple.mother.spouseCouples[0].Equals(couple))
                                        {
                                            oppositeCouple = couple.mother.spouseCouples[1];
                                        }
                                        else
                                        {
                                            oppositeCouple = couple.mother.spouseCouples[0];
                                        }

                                        double oppositeX = oppositeCouple.point.x;
                                        double motherX   = couple.point.x;
                                        bool   oppositeCoupleIsLeftOfMother = oppositeX < motherX;

                                        coupleIsReversed = oppositeCoupleIsLeftOfMother;
                                    }

                                    bool fatherToLeft = !coupleIsReversed;
                                    pullParents(model, couple, fatherToLeft);
                                }
                            }
                        }
                    }
                }
            };
        }
예제 #43
0
        public RepelIndividualSets(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                //foreach (PedigreeCouple pc in model.couples)
                //{
                //    pc.childOverlap = 0;
                //}

                int setId = 0;
                //for each generation,
                for (int generationalLevel = 0;
                    generationalLevel < model.individualSets.Count;
                    generationalLevel++)
                {
                    //sort the individual sets of the current generation
                    if (model.individualSets.ContainsKey(generationalLevel))
                    {
                        List<PedigreeIndividualSet> levelIndividualSets = model.individualSets[generationalLevel];
                        levelIndividualSets.Sort(delegate(PedigreeIndividualSet a, PedigreeIndividualSet b)
                        {
                            double ax = a.associatedCouple.point.x;
                            double bx = b.associatedCouple.point.x;
                            return ax.CompareTo(bx);
                        });

                        //then repel adjacent individual sets if necessary
                        for (int i = 0; i < levelIndividualSets.Count - 1; i++)
                        {
                            setId++;

                            PedigreeIndividualSet leftSet = levelIndividualSets[i];
                            PedigreeIndividualSet rightSet = levelIndividualSets[i + 1];

                            PedigreeIndividual rightmostOfLeftSet = GetRightmostIndividualOfSet(leftSet, rightSet);
                            PedigreeIndividual leftmostOfRightSet = GetLeftmostIndividualOfSet(rightSet, leftSet);
                            PedigreeIndividual rightmostOfRightSet = GetRightmostIndividualOfSet(rightSet, leftSet);
                            PedigreeIndividual leftmostOfLefttSet = GetLeftmostIndividualOfSet(leftSet, rightSet);

                            if (rightmostOfLeftSet != null && leftmostOfRightSet != null && rightmostOfRightSet != null && leftmostOfLefttSet != null)
                            {
                                //double interSetDistance = Math.Abs(leftmostOfRightSet.point.x - rightmostOfLeftSet.point.x);
                                double interSetDistance = leftmostOfRightSet.point.x - rightmostOfLeftSet.point.x;

                                double h = model.parameters.horizontalSpacing;

                                //if (leftmostOfRightSet.point.x < leftmostOfLefttSet.point.x && rightmostOfRightSet.point.x > rightmostOfLeftSet.point.x)
                                //{
                                //    interSetDistance = 0;
                                //}

                                double x = -1 * (interSetDistance - h);
                                //double x =  (interSetDistance - h);
                                //double force = 1 / (1 + Math.Pow(2, x));

                                double force = Math.Pow(2, x);
                                if (force > 5)
                                    force = 5;

                                force *= model.parameters.repelIndividualSetsStrength;

                                foreach (PedigreeIndividual leftIndividual in leftSet)
                                    leftIndividual.point.dx -= force;
                                foreach (PedigreeIndividual rightIndividual in rightSet)
                                    rightIndividual.point.dx += force;

                                ApplyForceToParents(leftSet, -force, x);
                                ApplyForceToParents(rightSet, force, x);

                            }
                        }
                    }
                }
            };
        }
예제 #44
0
 public void addLayoutStep(LayoutStep layoutStep)
 {
     this.steps.Add(layoutStep);
 }
예제 #45
0
        public RepelIndividuals(PedigreeModel model)
        {
            step = delegate()
            {
                foreach (PedigreeIndividual pi in model.individuals)
                {
                    foreach (PedigreeIndividual neighbor in model.individuals)
                    {
                        if (pi != neighbor)
                        {
                            if (Math.Abs(neighbor.point.y - pi.point.y) < (model.parameters.verticalSpacing / 2))
                            {
                                if (Math.Abs(neighbor.point.x - pi.point.x) < model.parameters.horizontalSpacing)
                                {
                                    if (!model.parameters.hideNonBloodRelatives || (neighbor.bloodRelative && pi.bloodRelative))
                                    {
                                        if (pi.Group == null || pi.Group.Contains(neighbor) == false)
                                        {
                                            if (neighbor.point.x < pi.point.x)
                                            {
                                                PedigreeUtils.PullTowardX(neighbor.point.x + model.parameters.horizontalSpacing, pi.point, model.parameters.repelIndividualSetsStrength, model);
                                            }
                                            else
                                            {
                                                PedigreeUtils.PullTowardX(neighbor.point.x - model.parameters.horizontalSpacing, pi.point, model.parameters.repelIndividualSetsStrength, model);
                                            }
                                        }
                                    }
                                }

                                //check for neighnor placed between person and spouse
                                if (neighbor.HraPerson.motherID == pi.HraPerson.motherID || neighbor.HraPerson.fatherID == pi.HraPerson.fatherID)
                                {
                                    foreach (PedigreeCouple pc in pi.spouseCouples)
                                    {
                                        PedigreeIndividual spouse;
                                        if (pc.mother == pi)
                                        {
                                            spouse = pc.father;
                                        }
                                        else
                                        {
                                            spouse = pc.mother;
                                        }

                                        if (spouse != null)
                                        {
                                            if (neighbor.point.x > Math.Min(pi.point.x, spouse.point.x) && neighbor.point.x < Math.Max(pi.point.x, spouse.point.x))
                                            {
                                                double x = neighbor.point.x;
                                                neighbor.point.x = pi.point.x;
                                                pi.point.x       = x;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            };
        }
예제 #46
0
        public LayoutCouples(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                    return;

                double hSpacing = model.parameters.horizontalSpacing;
                double halfHSpacing = hSpacing / 2;

                //for each couple, layout the mothers and fathers with no parents
                foreach (PedigreeCouple couple in model.couples)
                {
                    if (model.parameters.hideNonBloodRelatives && couple.mother.bloodRelative && !couple.father.bloodRelative)
                    {
                        couple.father.point.x = couple.mother.point.x;
                        couple.point.x = couple.mother.point.x;
                    }
                    else if (model.parameters.hideNonBloodRelatives && couple.father.bloodRelative && !couple.mother.bloodRelative)
                    {
                        couple.mother.point.x = couple.father.point.x;
                        couple.point.x = couple.father.point.x;
                    }
                    else
                    {

                        if (couple.mother != null && couple.father != null)
                        {
                            bool motherHasParents = couple.mother.Parents != null;
                            bool fatherHasParents = couple.father.Parents != null;

                            //if mother and father both have parents,
                            if (motherHasParents && fatherHasParents)
                            {
                                bool fatherToLeft = couple.father.Parents.point.x < couple.mother.Parents.point.x;
                                pullParents(model, couple, fatherToLeft);

                            }
                            //if the mother has parents but the father doesn't,
                            else if (motherHasParents && !fatherHasParents)
                            {
                                //then the mother will be pulled into position by
                                //the layout step for her sibship, so position the
                                //father depending on where the mother is:

                                //pull the father to the left of the mother
                                double goalX = couple.mother.point.x - hSpacing;
                                PointWithVelocity point = couple.father.point;
                                double strength = model.parameters.layoutCouplesStrength;
                                PedigreeUtils.PullTowardX(goalX, point, strength, model);
                            }
                            //if the father has parents but the mother diesn't,
                            else if (!motherHasParents && fatherHasParents)
                            {
                                //then the father will be pulled into position by
                                //the layout step for his sibship, so position the
                                //mother depending on where the father is:

                                //pull the mother to the right of the father
                                double goalX = couple.father.point.x + hSpacing;
                                PointWithVelocity point = couple.mother.point;
                                double strength = model.parameters.layoutCouplesStrength;
                                PedigreeUtils.PullTowardX(goalX, point, strength, model);

                            }
                            //if neither the father nor the mother has parents,
                            else if (!motherHasParents && !fatherHasParents)
                            {
                                //then position them according to their spouse position,
                                //placing the father on the left:
                                {
                                    //handle the case of half siblings:
                                    bool coupleIsReversed = false;
                                    if (couple.mother.spouseCouples.Count == 2)
                                    {
                                        PedigreeCouple oppositeCouple;
                                        if (couple.mother.spouseCouples[0].Equals(couple))
                                            oppositeCouple = couple.mother.spouseCouples[1];
                                        else
                                            oppositeCouple = couple.mother.spouseCouples[0];

                                        double oppositeX = oppositeCouple.point.x;
                                        double motherX = couple.point.x;
                                        bool oppositeCoupleIsLeftOfMother = oppositeX < motherX;

                                        coupleIsReversed = oppositeCoupleIsLeftOfMother;
                                    }

                                    bool fatherToLeft = !coupleIsReversed;
                                    pullParents(model, couple, fatherToLeft);

                                }
                            }
                        }
                    }
                }
            };
        }
예제 #47
0
        public CenterParents(PedigreeModel model)
        {
            step = delegate()
            {
                ////initialize the per-level ordering lists for each generation
                //for (int generationIndex = 0; generationIndex <= model.maxGenerationalLevel + 1; generationIndex++)
                //{

                //    List<PedigreeIndividual> generation = PedigreeUtils.GetIndividualsInGeneration(model, generationIndex);
                //    for (int i = 0; i < generation.Count; i++)
                //    {

                //    }
                //}
            };
                //if (model.couplesGraphIsPlanar)
                //{
                //    foreach (PedigreeCouple couple in model.couples)
                //    {

                //        if (!model.pointsBeingDragged.Contains(couple.point))
                //        {
                //            //compute the center for the couple
                //            double motherX = couple.mother.point.x;
                //            double motherY = couple.mother.point.y + model.parameters.individualSize / 2;
                //            double fatherX = couple.father.point.x;
                //            double fatherY = couple.father.point.y + model.parameters.individualSize / 2;
                //            double coupleCenterX = (motherX + fatherX) / 2;

                //            //compute the center for the couple's sibship
                //            double sibshipMinX = double.MaxValue;
                //            double sibshipMaxX = -double.MaxValue;
                //            foreach (PedigreeIndividual child in couple.children)
                //            {
                //                if (child.point.x < sibshipMinX)
                //                    sibshipMinX = (int)child.point.x;
                //                if (child.point.x > sibshipMaxX)
                //                    sibshipMaxX = (int)child.point.x;
                //            }

                //            double sibshipY = couple.point.y +
                //                model.parameters.verticalSpacing - model.parameters.individualSize / 2;
                //            double sibshipCenterX = (sibshipMinX + sibshipMaxX) / 2;

                //            //this is the middle point between parents and children from which
                //            //ideal positions of both are derived
                //            //double middleX = (sibshipCenterX + coupleCenterX) / 2;
                //            if (couple.mother.point.x < couple.father.point.x)
                //            {
                //                PedigreeUtils.PullTowardX(sibshipCenterX + (model.parameters.horizontalSpacing / 2), couple.mother.point, 2, model);
                //                PedigreeUtils.PullTowardX(sibshipCenterX - (model.parameters.horizontalSpacing / 2), couple.father.point, 2, model);
                //            }
                //            else
                //            {
                //                PedigreeUtils.PullTowardX(sibshipCenterX + (model.parameters.horizontalSpacing / 2), couple.mother.point, 2, model);
                //                PedigreeUtils.PullTowardX(sibshipCenterX - (model.parameters.horizontalSpacing / 2), couple.father.point, 2, model);
                //            }
                //             /**/
                //        }

                //        //if (Math.Abs(couple.mother.point.x - couple.father.point.x) > 120)
                //        //{
                //        //    if (couple.mother.point.x < couple.father.point.x)
                //        //    {
                //        //        PedigreeUtils.PullTowardX(couple.father.point.x + 60, couple.mother.point, 0.25, model);
                //        //        PedigreeUtils.PullTowardX(couple.mother.point.x - 60, couple.father.point, 0.25, model);
                //        //    }
                //        //    else
                //        //    {
                //        //        PedigreeUtils.PullTowardX(couple.father.point.x - 60, couple.mother.point, 0.25, model);
                //        //        PedigreeUtils.PullTowardX(couple.mother.point.x + 60, couple.father.point, 0.25, model);
                //        //    }
                //        //}
                //    }
                //}
                /* */

                /*
                //initialize the per-level ordering lists for each generation
                for (int generationIndex = 0; generationIndex <= model.maxGenerationalLevel + 1; generationIndex++)
                {

                    List<PedigreeIndividual> generation = PedigreeUtils.GetIndividualsInGeneration(model, generationIndex);
                    for (int i = 0; i < generation.Count; i++)
                    {
                        for (int j = i; j < generation.Count; j++)
                        {
                            PedigreeIndividual one = generation[i];
                            PedigreeIndividual two = generation[j];
                            double delta = Math.Abs(one.point.x - two.point.x);
                            if ( delta < (model.parameters.horizontalSpacing))
                            {
                                if (one.Parents.point.x < two.Parents.point.x)
                                {
                                    PedigreeUtils.PullTowardX(one.point.x - (model.parameters.horizontalSpacing - delta), one.point, 1, model);
                                    PedigreeUtils.PullTowardX(two.point.x + (model.parameters.horizontalSpacing - delta), two.point, 1, model);
                                }
                                else
                                {
                                    PedigreeUtils.PullTowardX(one.point.x + (model.parameters.horizontalSpacing - delta), one.point, 1, model);
                                    PedigreeUtils.PullTowardX(two.point.x - (model.parameters.horizontalSpacing - delta), two.point, 1, model);
                                }
                            }

                        }
                    }
                }

                if (model.couplesGraphIsPlanar)
                {
                    foreach (PedigreeCouple couple in model.couples)
                    {

                        if (!model.pointsBeingDragged.Contains(couple.point))
                        {
                            if (Math.Abs(couple.mother.point.x - couple.father.point.x) > (2 * model.parameters.horizontalSpacing))
                            {

                                //compute the center for the couple
                                double motherX = couple.mother.point.x;
                                double motherY = couple.mother.point.y + model.parameters.individualSize / 2;
                                double fatherX = couple.father.point.x;
                                double fatherY = couple.father.point.y + model.parameters.individualSize / 2;
                                double coupleCenterX = (motherX + fatherX) / 2;

                                if (couple.mother.point.x < couple.father.point.x)
                                {
                                    PedigreeUtils.PullTowardX(coupleCenterX + model.parameters.horizontalSpacing, couple.mother.point, 1, model);
                                    PedigreeUtils.PullTowardX(coupleCenterX - model.parameters.horizontalSpacing, couple.father.point, 1, model);
                                }
                                else
                                {
                                    PedigreeUtils.PullTowardX(coupleCenterX - model.parameters.horizontalSpacing, couple.mother.point, 1, model);
                                    PedigreeUtils.PullTowardX(coupleCenterX + model.parameters.horizontalSpacing, couple.father.point, 1, model);
                                }
                            }
                        }
                    }
                }
                 */
        }
예제 #48
0
파일: Pan.cs 프로젝트: mahitosh/HRA4
        public Pan(PedigreeModel model)
        {
            step = delegate()
            {

                //if the mouse was pressed and there were no couples being dragged,
                //drag the one under the mouse point.
                if (model.io.mousePressed)
                {
                    double x = model.io.mouseX;
                    double y = model.io.mouseY;
                    PointWithVelocity pointUnderCursor = GetPointUnderCursor(model, x, y);
                    if (pointUnderCursor == null)
                    {
                        x1 = x; y1 = y;
                        hOffset1 = model.parameters.hOffset;
                        vOffset1 = model.parameters.vOffset;
                        panInProgress = true;
                        //model.parameters.multiSelect = true;
                    }
                }
                else if (model.io.mouseReleased)
                {
                    if (model.SelectionLasso.Count > 3)
                    {
                        model.Selected.Clear();
                        Polygon p = new Polygon(model.SelectionLasso.ToArray());
                        foreach (PedigreeIndividual pi in model.individuals)
                        {
                            System.Drawing.Point scaled = new System.Drawing.Point((int)pi.point.x, (int)pi.point.y);

                            scaled.X += model.parameters.hOffset;
                            scaled.Y += model.parameters.vOffset;

                            scaled.X = (int)(model.parameters.scale * (double)scaled.X);
                            scaled.Y = (int)(model.parameters.scale * (double)scaled.Y);

                            pi.Selected = false;
                            if (p.Contains(scaled))
                            {
                                pi.Selected = true;
                                if(model.Selected.Contains(pi) == false)
                                    model.Selected.Add(pi);
                            }
                        }
                    }
                    else
                    {
                        //PedigreeIndividual s = PedigreeUtils.GetIndividualUnderPoint(model, x1, y1);
                        //if (s != null)
                        //{
                        //    s.Selected = true;
                        //    if(model.Selected.Contains(s) == false)
                        //            model.Selected.Add(s);
                        //}
                    }
                    model.parameters.multiSelect = false;
                    panInProgress = false;
                    model.SelectionLasso.Clear();

                }
                else if (panInProgress)
                {
                    double x2 = model.io.mouseX;
                    double y2 = model.io.mouseY;

                    if (model.parameters.multiSelect)
                    {
                        model.SelectionLasso.Add(new System.Drawing.Point((int)x2, (int)y2));
                    }
                    else
                    {
                        model.parameters.hOffset = (int)(hOffset1 + x2 - x1);
                        model.parameters.vOffset = (int)(vOffset1 + y2 - y1);
                    }
                }
            };
        }
예제 #49
0
        public DetectForceConvergence(PedigreeModel model, PedigreeController layoutEngine)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    layoutEngine.SetMode(PedigreeController.MANUAL);
                    return;
                }

                if (model.io.mouseDown == false)
                {
                    double delta = 0;
                    //bool moving = false;
                    foreach (PedigreeIndividual pi in model.individuals)
                    {
                        double meanX = 0;
                        double meanY = 0;
                        if (model.PositionHistoryX.ContainsKey(pi.HraPerson.relativeID))
                        {
                            model.PositionHistoryX[pi.HraPerson.relativeID].Add(pi.point.x);
                            if (model.PositionHistoryX[pi.HraPerson.relativeID].Count > model.parameters.PositionHistoryDepth)
                            {
                                model.PositionHistoryX[pi.HraPerson.relativeID].RemoveAt(0);
                            }
                        }
                        else
                        {
                            List <double> past = new List <double>();
                            past.Add(pi.point.x);
                            model.PositionHistoryX.Add(pi.HraPerson.relativeID, past);
                        }
                        foreach (double cur in model.PositionHistoryX[pi.HraPerson.relativeID])
                        {
                            meanX += cur;
                        }
                        meanX = meanX / ((double)(model.PositionHistoryX[pi.HraPerson.relativeID].Count));


                        if (model.PositionHistoryY.ContainsKey(pi.HraPerson.relativeID))
                        {
                            model.PositionHistoryY[pi.HraPerson.relativeID].Add(pi.point.y);
                            if (model.PositionHistoryY[pi.HraPerson.relativeID].Count > model.parameters.PositionHistoryDepth)
                            {
                                model.PositionHistoryY[pi.HraPerson.relativeID].RemoveAt(0);
                            }
                        }
                        else
                        {
                            List <double> past = new List <double>();
                            past.Add(pi.point.y);
                            model.PositionHistoryY.Add(pi.HraPerson.relativeID, past);
                        }
                        foreach (double cur in model.PositionHistoryY[pi.HraPerson.relativeID])
                        {
                            meanY += cur;
                        }
                        meanY = meanY / ((double)(model.PositionHistoryY[pi.HraPerson.relativeID].Count));

                        if (model.TargetPositions.ContainsKey(pi.HraPerson.relativeID))
                        {
                            delta += Math.Abs((model.TargetPositions[pi.HraPerson.relativeID].x - meanX));
                            delta += Math.Abs((model.TargetPositions[pi.HraPerson.relativeID].y - meanY));
                            model.TargetPositions[pi.HraPerson.relativeID].x = meanX;
                            model.TargetPositions[pi.HraPerson.relativeID].y = meanY;
                        }
                        else
                        {
                            PointWithVelocity pos = new PointWithVelocity();
                            pos.x = meanX;
                            pos.y = meanY;
                            model.TargetPositions.Add(pi.HraPerson.relativeID, pos);
                            delta += Math.Abs(meanX);
                            delta += Math.Abs(meanY);
                        }
                    }

                    if (delta / model.individuals.Count < 0.05)
                    {
                        if (model.converged == false)
                        {
                            if (layoutEngine.ModelConvergedCallback != null)
                            {
                                layoutEngine.ModelConvergedCallback.Invoke();
                            }
                        }
                        model.converged = true;
                    }
                    else
                    {
                        model.converged = false;
                    }
                }
            };
        }
예제 #50
0
        public Pan(PedigreeModel model)
        {
            step = delegate()
            {
                //if the mouse was pressed and there were no couples being dragged,
                //drag the one under the mouse point.
                if (model.io.mousePressed)
                {
                    double            x = model.io.mouseX;
                    double            y = model.io.mouseY;
                    PointWithVelocity pointUnderCursor = GetPointUnderCursor(model, x, y);
                    if (pointUnderCursor == null)
                    {
                        x1            = x; y1 = y;
                        hOffset1      = model.parameters.hOffset;
                        vOffset1      = model.parameters.vOffset;
                        panInProgress = true;
                        //model.parameters.multiSelect = true;
                    }
                }
                else if (model.io.mouseReleased)
                {
                    if (model.SelectionLasso.Count > 3)
                    {
                        model.Selected.Clear();
                        Polygon p = new Polygon(model.SelectionLasso.ToArray());
                        foreach (PedigreeIndividual pi in model.individuals)
                        {
                            System.Drawing.Point scaled = new System.Drawing.Point((int)pi.point.x, (int)pi.point.y);

                            scaled.X += model.parameters.hOffset;
                            scaled.Y += model.parameters.vOffset;

                            scaled.X = (int)(model.parameters.scale * (double)scaled.X);
                            scaled.Y = (int)(model.parameters.scale * (double)scaled.Y);



                            pi.Selected = false;
                            if (p.Contains(scaled))
                            {
                                pi.Selected = true;
                                if (model.Selected.Contains(pi) == false)
                                {
                                    model.Selected.Add(pi);
                                }
                            }
                        }
                    }
                    else
                    {
                        //PedigreeIndividual s = PedigreeUtils.GetIndividualUnderPoint(model, x1, y1);
                        //if (s != null)
                        //{
                        //    s.Selected = true;
                        //    if(model.Selected.Contains(s) == false)
                        //            model.Selected.Add(s);
                        //}
                    }
                    model.parameters.multiSelect = false;
                    panInProgress = false;
                    model.SelectionLasso.Clear();
                }
                else if (panInProgress)
                {
                    double x2 = model.io.mouseX;
                    double y2 = model.io.mouseY;

                    if (model.parameters.multiSelect)
                    {
                        model.SelectionLasso.Add(new System.Drawing.Point((int)x2, (int)y2));
                    }
                    else
                    {
                        model.parameters.hOffset = (int)(hOffset1 + x2 - x1);
                        model.parameters.vOffset = (int)(vOffset1 + y2 - y1);
                    }
                }
            };
        }
예제 #51
0
        public StaticLayout(PedigreeModel model, PedigreeController layoutEngine)
        {
            transitionToStaticLayout = delegate()
            {
                if (model.cycles > 1000 || (model.cycles>800 && model.couplesGraphIsPlanar && model.layoutIsValid==false))// && model.forcesHaveConverged)
                {
                    //switch modes from self organizing to static
                    if (layoutEngine.GetMode() == PedigreeController.SELF_ORGANIZING)
                    {
                        model.TargetPositions.Clear();
                        foreach (PedigreeIndividual pi in model.individuals)
                        {
                            PointWithVelocity pos = new PointWithVelocity();
                            pos.x = pi.point.x;
                            pos.y = pi.point.y;
                            model.TargetPositions.Add(pi.HraPerson.relativeID, pos);
                        }

                        layoutEngine.SetMode(PedigreeController.STATIC_LAYOUT);
                        generations = new List<List<PedigreeIndividual>>();
                        //initialize the per-level ordering lists for each generation
                        for (int generation = 0; generation <= model.maxGenerationalLevel+1; generation++)
                            generations.Add(PedigreeUtils.GetIndividualsInGeneration(model, generation));

                        readyToRunStaticLayout = true;

                    }
                }
            };
            step = delegate()
            {
                if (runOnce && readyToRunStaticLayout)
                {
                    failedAttempts++;

                    readyToRunStaticLayout = false;
                    double spacing = model.parameters.verticalSpacing;
                    double centerY = (model.displayYMin + model.displayYMax) / 2;
                    double offset = centerY - (model.maxGenerationalLevel + 1) * spacing / 2;

                    double initialX = 30;
                    double initialY = centerY;
                    //for each generation, bottom to top...
                    for (int g = generations.Count - 1; g >= 0; g--)
                    //for(int i = 0;i<generations.Count;i++)
                    {
                        List<PedigreeIndividual> generation = generations[g];

                        //compute the y positions
                        foreach (PedigreeIndividual individual in generation)
                            individual.point.y = g * spacing + offset;

                        //for the bottom level, just position with even spaces
                        if (g == generations.Count - 1)
                        {
                            double x = initialX;
                            foreach (PedigreeIndividual individual in generation)
                            {
                                individual.point.x = x += model.parameters.horizontalSpacing;
                                individual.wasMoved = true;
                            }
                        }
                        //for all the other levels...
                        else
                        {
                            //First compute locations of parents centered around their children
                            //and place the parent couples exactly at those centers:

                            //for each individual in the current generation...
                            for (int j = 0; j < generation.Count; j++)
                            {
                                PedigreeIndividual individual = generation[j];

                                //if the current individual has a spouse...
                                foreach (PedigreeCouple pc in individual.spouseCouples)
                                {
                                    //so we compute the center of this couple's sibship,
                                    double sibshipCenterX = pc.GetSibshipCenterX(model);

                                    //and position the couple such that its center is the same as the sibship center

                                    if (pc.father.point.x < pc.mother.point.x)
                                    {
                                        pc.father.point.x = sibshipCenterX - model.parameters.horizontalSpacing / 2;
                                        pc.mother.point.x = sibshipCenterX + model.parameters.horizontalSpacing / 2;
                                    }
                                    else
                                    {

                                        pc.mother.point.x = sibshipCenterX - model.parameters.horizontalSpacing / 2;
                                        pc.father.point.x = sibshipCenterX + model.parameters.horizontalSpacing / 2;
                                    }
                                    pc.mother.wasMoved = pc.father.wasMoved = true;

                                }
                            }
                            /**/

                            //Second, position the outer children:
                            //find the leftmost individual that was placed
                            for (int inc = 1; inc >= -1; inc -= 2)
                            {
                                for (int j = inc == 1 ? 0 : generation.Count - 1;
                                             inc == 1 ? j < generation.Count : j >= 0;
                                             j += inc)
                                {
                                    if (generation[j].wasMoved)
                                    {

                                        for (int i = j - inc;
                                             inc == 1 ? i >= 0 : i < generation.Count; i -= inc)
                                        {
                                            generation[i].point.x = generation[i + inc].point.x - inc * model.parameters.horizontalSpacing;
                                            generation[i].wasMoved = true;
                                        }
                                        break;
                                    }
                                }
                            }

                            //Third, detect "too close"ness and move individuals to be perfectly spaced,
                            //propagating left to right and downward through children
                            for (int j = 0; j < generation.Count - 1; j++)
                            {
                                PedigreeIndividual left = generation[j];
                                PedigreeIndividual right = generation[j + 1];
                                //if folks are too close...
                                if (right.point.x - left.point.x < model.parameters.horizontalSpacing)
                                {
                                    //move the individual on the right such that spacing is perfect,
                                    //based on the current position of the individual on the left
                                    double dx = left.point.x + model.parameters.horizontalSpacing - right.point.x;
                                    right.point.x += dx;
                                    right.wasMoved = true;

                                    for (int z = j + 2; z < generation.Count - 1; z++)
                                    {
                                        PedigreeIndividual farRight = generation[z];
                                        farRight.point.x += dx;
                                        farRight.wasMoved = true;

                                    }
                                    //and through their children
                                    foreach (PedigreeCouple pc in left.spouseCouples)
                                    {

                                        PedigreeIndividual spouse;
                                        if (left.HraPerson.relativeID == pc.mother.HraPerson.relativeID)
                                            spouse = pc.father;
                                        else
                                            spouse = pc.mother;

                                        if (right.HraPerson.relativeID == spouse.HraPerson.relativeID)
                                        {
                                            //PedigreeCouple couple = GetCoupleFromLR(model, left, right);
                                            //if (couple != null)
                                                MoveChildren(dx, pc, model);
                                        }
                                    }

                                }
                            }

                        }
                    }

                    for (int g = 0; g < generations.Count - 1; g++)
                    {
                        List<PedigreeIndividual> generation = generations[g];
                        //for (int j = 0; j <  1; j++)
                        for (int j = generation.Count - 1; j >= 0; j--)
                        {
                            PedigreeIndividual left = generation[j];
                            if (left.HasSpouse())
                            {
                                //PedigreeCouple couple = GetCoupleFromLR(model, left, right);
                                foreach (PedigreeCouple pc in model.couples)
                                {
                                    double parentsX = (pc.mother.point.x + pc.father.point.x) / 2;
                                    if (pc.mother == left || pc.father == left)
                                    {
                                        double kidsX = 0;
                                        foreach (PedigreeIndividual kid in pc.children)
                                        {
                                            kidsX += kid.point.x;
                                        }
                                        kidsX = kidsX / ((double)(pc.children.Count));
                                        foreach (PedigreeIndividual kid in pc.children)
                                        {
                                            kid.point.x += (parentsX - kidsX);

                                            foreach (PedigreeCouple kidsPC in kid.spouseCouples)
                                            {

                                                PedigreeIndividual spouse;
                                                if (left.HraPerson.relativeID == pc.mother.HraPerson.relativeID)
                                                    spouse = pc.father;
                                                else
                                                    spouse = pc.mother;

                                                spouse.point.x += (parentsX - kidsX);
                                                spouse.wasMoved = true;

                                            }

                                        }
                                    }
                                }
                            }
                        }
                    }

                    //after positioning everyone, center the pedigree on the screen:
                    double minX = double.MaxValue;
                    double maxX = -minX;

                    foreach (PointWithVelocity point in model.points)
                        if (point.x < minX)
                            minX = point.x;
                        else if (point.x > maxX)
                            maxX = point.x;

                    double centerX = (minX + maxX) / 2;
                    double idealCenterX = (model.displayXMin + model.displayYMax) / 2;
                    double off = idealCenterX - centerX;
                    foreach (PointWithVelocity point in model.points)
                        point.x = point.x + off;
                }

                //if (LayoutIsValid(model))
                if (true)
                {
                    //model.parameters.repelIndividualSetsStrength = 1;

                    layoutEngine.SetMode(PedigreeController.MANUAL);
                }
                //else
                //{

                    //layoutEngine.SetMode(PedigreeController.SELF_ORGANIZING);

                    //if (failedAttempts < 5)
                    //{

                        //model.parameters.repelIndividualSetsStrength += 0.5;
                    //}
                    //else if (failedAttempts < 10)
                    //{
                    //    model.parameters.repelIndividualSetsStrength = 1;
                    //    foreach (PointWithVelocity p in model.points)
                    //    {
                    //        double newX = autoRand.NextDouble() * (model.displayXMax - 1);
                    //        double newY = autoRand.NextDouble() * (model.displayYMax - 1);
                    //        p.x = newX;
                    //        p.dx = 0;
                    //        p.y = newY;
                    //        p.dy = 0;

                    //    }
                    //}
                    //else
                    //{
                    //    layoutEngine.SetMode(PedigreeController.MANUAL);
                    //}
                     /**/
                //}

            };
        }
예제 #52
0
        public RepelIndividualSets(PedigreeModel model)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    return;
                }

                //foreach (PedigreeCouple pc in model.couples)
                //{
                //    pc.childOverlap = 0;
                //}

                int setId = 0;
                //for each generation,
                for (int generationalLevel = 0;
                     generationalLevel < model.individualSets.Count;
                     generationalLevel++)
                {
                    //sort the individual sets of the current generation
                    if (model.individualSets.ContainsKey(generationalLevel))
                    {
                        List <PedigreeIndividualSet> levelIndividualSets = model.individualSets[generationalLevel];
                        levelIndividualSets.Sort(delegate(PedigreeIndividualSet a, PedigreeIndividualSet b)
                        {
                            double ax = a.associatedCouple.point.x;
                            double bx = b.associatedCouple.point.x;
                            return(ax.CompareTo(bx));
                        });

                        //then repel adjacent individual sets if necessary
                        for (int i = 0; i < levelIndividualSets.Count - 1; i++)
                        {
                            setId++;

                            PedigreeIndividualSet leftSet  = levelIndividualSets[i];
                            PedigreeIndividualSet rightSet = levelIndividualSets[i + 1];

                            PedigreeIndividual rightmostOfLeftSet  = GetRightmostIndividualOfSet(leftSet, rightSet);
                            PedigreeIndividual leftmostOfRightSet  = GetLeftmostIndividualOfSet(rightSet, leftSet);
                            PedigreeIndividual rightmostOfRightSet = GetRightmostIndividualOfSet(rightSet, leftSet);
                            PedigreeIndividual leftmostOfLefttSet  = GetLeftmostIndividualOfSet(leftSet, rightSet);

                            if (rightmostOfLeftSet != null && leftmostOfRightSet != null && rightmostOfRightSet != null && leftmostOfLefttSet != null)
                            {
                                //double interSetDistance = Math.Abs(leftmostOfRightSet.point.x - rightmostOfLeftSet.point.x);
                                double interSetDistance = leftmostOfRightSet.point.x - rightmostOfLeftSet.point.x;

                                double h = model.parameters.horizontalSpacing;

                                //if (leftmostOfRightSet.point.x < leftmostOfLefttSet.point.x && rightmostOfRightSet.point.x > rightmostOfLeftSet.point.x)
                                //{
                                //    interSetDistance = 0;
                                //}

                                double x = -1 * (interSetDistance - h);
                                //double x =  (interSetDistance - h);
                                //double force = 1 / (1 + Math.Pow(2, x));

                                double force = Math.Pow(2, x);
                                if (force > 5)
                                {
                                    force = 5;
                                }

                                force *= model.parameters.repelIndividualSetsStrength;


                                foreach (PedigreeIndividual leftIndividual in leftSet)
                                {
                                    leftIndividual.point.dx -= force;
                                }
                                foreach (PedigreeIndividual rightIndividual in rightSet)
                                {
                                    rightIndividual.point.dx += force;
                                }

                                ApplyForceToParents(leftSet, -force, x);
                                ApplyForceToParents(rightSet, force, x);
                            }
                        }
                    }
                }
            };
        }
예제 #53
0
        public AttractCouples(PedigreeModel model)
        {
            step = delegate()
            {
                foreach (PedigreeCouple pc in model.couples)
                {
                    if ((pc.mother != null) && (pc.father != null))
                    {
                        if (pc.mother.Mother != null &&
                            pc.mother.Father != null &&
                            pc.father.Mother != null &&
                            pc.father.Father != null)
                        {
                            double motherAvgX = (pc.mother.Mother.point.x + pc.mother.Father.point.x) / 2;
                            double fatherAvgX = (pc.father.Mother.point.x + pc.father.Father.point.x) / 2;

                            if (pc.mother.point.x > pc.father.point.x && motherAvgX < fatherAvgX)
                            {
                                double temp = pc.mother.point.x;
                                pc.mother.point.x = pc.father.point.x;
                                pc.father.point.x = temp;
                            }
                            else if (pc.father.point.x > pc.mother.point.x && fatherAvgX < motherAvgX)
                            {
                                double temp = pc.mother.point.x;
                                pc.mother.point.x = pc.father.point.x;
                                pc.father.point.x = temp;
                            }
                        }

                        if (pc.children.Count > 0)
                        {
                            double xAcc   = 0;
                            double yAcc   = 0;
                            double sibMin = double.MaxValue;
                            double sibMax = double.MinValue;
                            foreach (PedigreeIndividual kid in pc.children)
                            {
                                xAcc += kid.point.x;
                                yAcc += kid.point.y;
                                if (sibMin > kid.point.x)
                                {
                                    sibMin = kid.point.x;
                                }
                                if (sibMax < kid.point.x)
                                {
                                    sibMax = kid.point.x;
                                }
                            }
                            xAcc  = (sibMin + sibMax) / 2;
                            yAcc /= (double)pc.children.Count;

                            double distance  = Math.Abs(pc.mother.point.x - pc.father.point.x);
                            double coupleAvg = (pc.mother.point.x + pc.father.point.x) / (2.0);

                            if (!model.parameters.hideNonBloodRelatives || (pc.mother.bloodRelative && pc.father.bloodRelative))
                            {
                                if (pc.mother.point.x < pc.father.point.x)
                                {
                                    PedigreeUtils.PullTowardX(xAcc - (distance / 2), pc.mother.point, 0.1, model);
                                    PedigreeUtils.PullTowardX(xAcc + (distance / 2), pc.father.point, 0.1, model);
                                }
                                else
                                {
                                    PedigreeUtils.PullTowardX(xAcc + (distance / 2), pc.mother.point, 0.1, model);
                                    PedigreeUtils.PullTowardX(xAcc - (distance / 2), pc.father.point, 0.1, model);
                                }


                                List <PedigreeIndividual> kidsPulledToParents = new List <PedigreeIndividual>();
                                if (Math.Abs(pc.mother.point.x - pc.father.point.x) < (0.90 * model.parameters.horizontalSpacing))
                                {
                                    SeperateCouple(pc, model, xAcc, ref kidsPulledToParents);
                                }
                            }
                            else
                            {
                                if (model.parameters.hideNonBloodRelatives)
                                {
                                    if (pc.mother.bloodRelative && !pc.father.bloodRelative)
                                    {
                                        PedigreeUtils.PullTowardX(pc.mother.point.x, pc.father.point, 0.1, model);
                                    }
                                    else if (!pc.mother.bloodRelative && pc.father.bloodRelative)
                                    {
                                        PedigreeUtils.PullTowardX(pc.father.point.x, pc.mother.point, 0.1, model);
                                    }
                                }

                                pc.mother.point.x = coupleAvg;
                                pc.father.point.x = coupleAvg;
                            }
                        }
                    }
                }
            };
        }
예제 #54
0
        public DetectForceConvergence(PedigreeModel model, PedigreeController layoutEngine)
        {
            step = delegate()
            {
                if (model.individuals.Count < 2)
                {
                    layoutEngine.SetMode(PedigreeController.MANUAL);
                    return;
                }

                if (model.io.mouseDown == false)
                {
                    double delta = 0;
                    //bool moving = false;
                    foreach (PedigreeIndividual pi in model.individuals)
                    {
                        double meanX = 0;
                        double meanY = 0;
                        if (model.PositionHistoryX.ContainsKey(pi.HraPerson.relativeID))
                        {
                            model.PositionHistoryX[pi.HraPerson.relativeID].Add(pi.point.x);
                            if (model.PositionHistoryX[pi.HraPerson.relativeID].Count > model.parameters.PositionHistoryDepth)
                                model.PositionHistoryX[pi.HraPerson.relativeID].RemoveAt(0);
                        }
                        else
                        {
                            List<double> past = new List<double>();
                            past.Add(pi.point.x);
                            model.PositionHistoryX.Add(pi.HraPerson.relativeID, past);
                        }
                        foreach (double cur in model.PositionHistoryX[pi.HraPerson.relativeID])
                        {
                            meanX += cur;
                        }
                        meanX = meanX / ((double)(model.PositionHistoryX[pi.HraPerson.relativeID].Count));

                        if (model.PositionHistoryY.ContainsKey(pi.HraPerson.relativeID))
                        {
                            model.PositionHistoryY[pi.HraPerson.relativeID].Add(pi.point.y);
                            if (model.PositionHistoryY[pi.HraPerson.relativeID].Count > model.parameters.PositionHistoryDepth)
                                model.PositionHistoryY[pi.HraPerson.relativeID].RemoveAt(0);
                        }
                        else
                        {
                            List<double> past = new List<double>();
                            past.Add(pi.point.y);
                            model.PositionHistoryY.Add(pi.HraPerson.relativeID, past);
                        }
                        foreach (double cur in model.PositionHistoryY[pi.HraPerson.relativeID])
                        {
                            meanY += cur;
                        }
                        meanY = meanY / ((double)(model.PositionHistoryY[pi.HraPerson.relativeID].Count));

                        if (model.TargetPositions.ContainsKey(pi.HraPerson.relativeID))
                        {
                            delta += Math.Abs((model.TargetPositions[pi.HraPerson.relativeID].x - meanX));
                            delta += Math.Abs((model.TargetPositions[pi.HraPerson.relativeID].y - meanY));
                            model.TargetPositions[pi.HraPerson.relativeID].x = meanX;
                            model.TargetPositions[pi.HraPerson.relativeID].y = meanY;
                        }
                        else
                        {
                            PointWithVelocity pos = new PointWithVelocity();
                            pos.x = meanX;
                            pos.y = meanY;
                            model.TargetPositions.Add(pi.HraPerson.relativeID, pos);
                            delta += Math.Abs(meanX);
                            delta += Math.Abs(meanY);
                        }

                    }

                    if (delta / model.individuals.Count < 0.05)
                    {
                        if (model.converged == false)
                        {
                            if (layoutEngine.ModelConvergedCallback != null)
                                layoutEngine.ModelConvergedCallback.Invoke();
                        }
                        model.converged = true;
                    }
                    else
                    {
                        model.converged = false;
                    }
                }
            };
        }
예제 #55
0
        public StaticLayout(PedigreeModel model, PedigreeController layoutEngine)
        {
            transitionToStaticLayout = delegate()
            {
                if (model.cycles > 1000 || (model.cycles > 800 && model.couplesGraphIsPlanar && model.layoutIsValid == false))// && model.forcesHaveConverged)
                {
                    //switch modes from self organizing to static
                    if (layoutEngine.GetMode() == PedigreeController.SELF_ORGANIZING)
                    {
                        model.TargetPositions.Clear();
                        foreach (PedigreeIndividual pi in model.individuals)
                        {
                            PointWithVelocity pos = new PointWithVelocity();
                            pos.x = pi.point.x;
                            pos.y = pi.point.y;
                            model.TargetPositions.Add(pi.HraPerson.relativeID, pos);
                        }

                        layoutEngine.SetMode(PedigreeController.STATIC_LAYOUT);
                        generations = new List <List <PedigreeIndividual> >();
                        //initialize the per-level ordering lists for each generation
                        for (int generation = 0; generation <= model.maxGenerationalLevel + 1; generation++)
                        {
                            generations.Add(PedigreeUtils.GetIndividualsInGeneration(model, generation));
                        }

                        readyToRunStaticLayout = true;
                    }
                }
            };
            step = delegate()
            {
                if (runOnce && readyToRunStaticLayout)
                {
                    failedAttempts++;

                    readyToRunStaticLayout = false;
                    double spacing = model.parameters.verticalSpacing;
                    double centerY = (model.displayYMin + model.displayYMax) / 2;
                    double offset  = centerY - (model.maxGenerationalLevel + 1) * spacing / 2;

                    double initialX = 30;
                    double initialY = centerY;
                    //for each generation, bottom to top...
                    for (int g = generations.Count - 1; g >= 0; g--)
                    //for(int i = 0;i<generations.Count;i++)
                    {
                        List <PedigreeIndividual> generation = generations[g];

                        //compute the y positions
                        foreach (PedigreeIndividual individual in generation)
                        {
                            individual.point.y = g * spacing + offset;
                        }

                        //for the bottom level, just position with even spaces
                        if (g == generations.Count - 1)
                        {
                            double x = initialX;
                            foreach (PedigreeIndividual individual in generation)
                            {
                                individual.point.x  = x += model.parameters.horizontalSpacing;
                                individual.wasMoved = true;
                            }
                        }
                        //for all the other levels...
                        else
                        {
                            //First compute locations of parents centered around their children
                            //and place the parent couples exactly at those centers:

                            //for each individual in the current generation...
                            for (int j = 0; j < generation.Count; j++)
                            {
                                PedigreeIndividual individual = generation[j];

                                //if the current individual has a spouse...
                                foreach (PedigreeCouple pc in individual.spouseCouples)
                                {
                                    //so we compute the center of this couple's sibship,
                                    double sibshipCenterX = pc.GetSibshipCenterX(model);

                                    //and position the couple such that its center is the same as the sibship center

                                    if (pc.father.point.x < pc.mother.point.x)
                                    {
                                        pc.father.point.x = sibshipCenterX - model.parameters.horizontalSpacing / 2;
                                        pc.mother.point.x = sibshipCenterX + model.parameters.horizontalSpacing / 2;
                                    }
                                    else
                                    {
                                        pc.mother.point.x = sibshipCenterX - model.parameters.horizontalSpacing / 2;
                                        pc.father.point.x = sibshipCenterX + model.parameters.horizontalSpacing / 2;
                                    }
                                    pc.mother.wasMoved = pc.father.wasMoved = true;
                                }
                            }
                            /**/

                            //Second, position the outer children:
                            //find the leftmost individual that was placed
                            for (int inc = 1; inc >= -1; inc -= 2)
                            {
                                for (int j = inc == 1 ? 0 : generation.Count - 1;
                                     inc == 1 ? j < generation.Count : j >= 0;
                                     j += inc)
                                {
                                    if (generation[j].wasMoved)
                                    {
                                        for (int i = j - inc;
                                             inc == 1 ? i >= 0 : i < generation.Count; i -= inc)
                                        {
                                            generation[i].point.x  = generation[i + inc].point.x - inc * model.parameters.horizontalSpacing;
                                            generation[i].wasMoved = true;
                                        }
                                        break;
                                    }
                                }
                            }



                            //Third, detect "too close"ness and move individuals to be perfectly spaced,
                            //propagating left to right and downward through children
                            for (int j = 0; j < generation.Count - 1; j++)
                            {
                                PedigreeIndividual left  = generation[j];
                                PedigreeIndividual right = generation[j + 1];
                                //if folks are too close...
                                if (right.point.x - left.point.x < model.parameters.horizontalSpacing)
                                {
                                    //move the individual on the right such that spacing is perfect,
                                    //based on the current position of the individual on the left
                                    double dx = left.point.x + model.parameters.horizontalSpacing - right.point.x;
                                    right.point.x += dx;
                                    right.wasMoved = true;

                                    for (int z = j + 2; z < generation.Count - 1; z++)
                                    {
                                        PedigreeIndividual farRight = generation[z];
                                        farRight.point.x += dx;
                                        farRight.wasMoved = true;
                                    }
                                    //and through their children
                                    foreach (PedigreeCouple pc in left.spouseCouples)
                                    {
                                        PedigreeIndividual spouse;
                                        if (left.HraPerson.relativeID == pc.mother.HraPerson.relativeID)
                                        {
                                            spouse = pc.father;
                                        }
                                        else
                                        {
                                            spouse = pc.mother;
                                        }

                                        if (right.HraPerson.relativeID == spouse.HraPerson.relativeID)
                                        {
                                            //PedigreeCouple couple = GetCoupleFromLR(model, left, right);
                                            //if (couple != null)
                                            MoveChildren(dx, pc, model);
                                        }
                                    }
                                }
                            }
                        }
                    }


                    for (int g = 0; g < generations.Count - 1; g++)
                    {
                        List <PedigreeIndividual> generation = generations[g];
                        //for (int j = 0; j <  1; j++)
                        for (int j = generation.Count - 1; j >= 0; j--)
                        {
                            PedigreeIndividual left = generation[j];
                            if (left.HasSpouse())
                            {
                                //PedigreeCouple couple = GetCoupleFromLR(model, left, right);
                                foreach (PedigreeCouple pc in model.couples)
                                {
                                    double parentsX = (pc.mother.point.x + pc.father.point.x) / 2;
                                    if (pc.mother == left || pc.father == left)
                                    {
                                        double kidsX = 0;
                                        foreach (PedigreeIndividual kid in pc.children)
                                        {
                                            kidsX += kid.point.x;
                                        }
                                        kidsX = kidsX / ((double)(pc.children.Count));
                                        foreach (PedigreeIndividual kid in pc.children)
                                        {
                                            kid.point.x += (parentsX - kidsX);

                                            foreach (PedigreeCouple kidsPC in kid.spouseCouples)
                                            {
                                                PedigreeIndividual spouse;
                                                if (left.HraPerson.relativeID == pc.mother.HraPerson.relativeID)
                                                {
                                                    spouse = pc.father;
                                                }
                                                else
                                                {
                                                    spouse = pc.mother;
                                                }

                                                spouse.point.x += (parentsX - kidsX);
                                                spouse.wasMoved = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }


                    //after positioning everyone, center the pedigree on the screen:
                    double minX = double.MaxValue;
                    double maxX = -minX;

                    foreach (PointWithVelocity point in model.points)
                    {
                        if (point.x < minX)
                        {
                            minX = point.x;
                        }
                        else if (point.x > maxX)
                        {
                            maxX = point.x;
                        }
                    }

                    double centerX      = (minX + maxX) / 2;
                    double idealCenterX = (model.displayXMin + model.displayYMax) / 2;
                    double off          = idealCenterX - centerX;
                    foreach (PointWithVelocity point in model.points)
                    {
                        point.x = point.x + off;
                    }
                }

                //if (LayoutIsValid(model))
                if (true)
                {
                    //model.parameters.repelIndividualSetsStrength = 1;

                    layoutEngine.SetMode(PedigreeController.MANUAL);
                }
                //else
                //{

                //layoutEngine.SetMode(PedigreeController.SELF_ORGANIZING);

                //if (failedAttempts < 5)
                //{

                //model.parameters.repelIndividualSetsStrength += 0.5;
                //}
                //else if (failedAttempts < 10)
                //{
                //    model.parameters.repelIndividualSetsStrength = 1;
                //    foreach (PointWithVelocity p in model.points)
                //    {
                //        double newX = autoRand.NextDouble() * (model.displayXMax - 1);
                //        double newY = autoRand.NextDouble() * (model.displayYMax - 1);
                //        p.x = newX;
                //        p.dx = 0;
                //        p.y = newY;
                //        p.dy = 0;

                //    }
                //}
                //else
                //{
                //    layoutEngine.SetMode(PedigreeController.MANUAL);
                //}
                /**/
                //}
            };
        }