Exemplo n.º 1
0
        private void SeperateCouple(PedigreeCouple pc, PedigreeModel model, double sibMedian, ref List <PedigreeIndividual> kidsPulledToParents)
        {
            if (!model.parameters.hideNonBloodRelatives || (pc.mother.bloodRelative && pc.father.bloodRelative))
            {
                if (pc.mother.point.x < pc.father.point.x)
                {
                    PedigreeUtils.PullTowardX(pc.mother.point.x - 1, pc.mother.point, 0.1, model);
                    PedigreeUtils.PullTowardX(pc.father.point.x + 1, pc.father.point, 0.1, model);
                }
                else
                {
                    PedigreeUtils.PullTowardX(pc.mother.point.x + 1, pc.mother.point, 0.1, model);
                    PedigreeUtils.PullTowardX(pc.father.point.x - 1, pc.father.point, 0.1, model);
                }
            }
            else
            {
                double coupleAvg = (pc.mother.point.x + pc.father.point.x) / (2.0);
                pc.mother.point.x = coupleAvg;
                pc.father.point.x = coupleAvg;
            }

            double target = ((pc.mother.point.x + pc.father.point.x) / 2) - sibMedian;

            foreach (PedigreeIndividual pi in pc.children)
            {
                if (kidsPulledToParents.Contains(pi) == false)
                {
                    PedigreeUtils.PullTowardX((pc.mother.point.x + pc.father.point.x) / 2, pi.point, 0.075, model);
                    kidsPulledToParents.Add(pi);
                }
                //PedigreeUtils.PullTowardX(pi.point.x + target, pi.point, 0.1, model);
            }

            foreach (PedigreeCouple nested_pc in model.couples)
            {
                if (nested_pc != pc)
                {
                    if (pc.children.Contains(nested_pc.mother) || pc.children.Contains(nested_pc.father))
                    {
                        SeperateCouple(nested_pc, model, sibMedian, ref kidsPulledToParents);
                    }
                }
            }
        }
Exemplo n.º 2
0
 private void ApplyForceToParents(PedigreeIndividualSet iSet, double force)
 {
     foreach (PedigreeIndividual individual in iSet)
     {
         if (individual.Parents != null)
         {
             PedigreeCouple parents = individual.Parents;
             //only apply the force to the parent which has a parent
             if (parents.mother.Parents != null)
             {
                 parents.mother.point.dx += force;
             }
             if (parents.father.Parents != null)
             {
                 parents.father.point.dx += force;
             }
         }
     }
 }
        private static void repelAllCouplePairs(PedigreeModel model)
        {
            try
            {
                int n = model.couples.Count;

                //consider the upper triangle (all pairs)
                for (int i = 0; i < n; i++)
                {
                    for (int j = i + 1; j < n; j++)
                    {
                        PedigreeCouple coupleA = model.couples[i];
                        PedigreeCouple coupleB = model.couples[j];

                        if (coupleA.GenerationalLevel == coupleB.GenerationalLevel)
                        {
                            PointWithVelocity a = coupleA.point;
                            PointWithVelocity b = coupleB.point;

                            //separate exactly overlapping points
                            if (b.x - a.x == 0)
                            {
                                a.x += epsilon;
                            }

                            double distance = b.x - a.x;
                            double spread   = 200;
                            double forceX   = 10 * repulsionStrength * spread / (distance * distance + spread);

                            forceX *= b.x > a.x ? 1 : -1;

                            a.dx -= forceX;
                            b.dx += forceX;
                        }
                    }
                }
            }
            catch (Exception e)
            {
                Logger.Instance.WriteToLog(e.ToString());
            }
        }
Exemplo n.º 4
0
        private static void pullParents(PedigreeModel model, PedigreeCouple couple, bool fatherToLeft)
        {
            double halfHSpacing = model.parameters.horizontalSpacing / 2;
            double reversal     = fatherToLeft ? 1 : -1;
            //position the father to the left
            {
                double            goalX    = couple.point.x - reversal * halfHSpacing;
                PointWithVelocity point    = couple.father.point;
                double            strength = model.parameters.layoutCouplesStrength;
                PedigreeUtils.PullTowardX(goalX, point, strength, model);
            }

            //position the mother to the right
            {
                double            goalX    = couple.point.x + reversal * halfHSpacing;
                PointWithVelocity point    = couple.mother.point;
                double            strength = model.parameters.layoutCouplesStrength;
                PedigreeUtils.PullTowardX(goalX, point, strength, model);
            }
        }
Exemplo n.º 5
0
        private static void MoveChildren(double dx, PedigreeCouple couple, PedigreeModel model)
        {
            foreach (PedigreeIndividual child in couple.children)
            {
                child.point.x += dx;
                child.wasMoved = true;
                foreach (PedigreeCouple pc in child.spouseCouples)
                {
                    PedigreeIndividual spouse;
                    if (child.HraPerson.relativeID == pc.mother.HraPerson.relativeID)
                    {
                        spouse = pc.father;
                    }
                    else
                    {
                        spouse = pc.mother;
                    }

                    if (spouse.Parents != null)
                    {
                        PedigreeCouple nestedCouple = GetCoupleFromLR(model, child, spouse);
                        if (nestedCouple != null)
                        {
                            MoveChildren(dx / 2, nestedCouple, model);
                        }
                    }
                    else
                    {
                        spouse.point.x += dx;
                        spouse.wasMoved = true;
                        PedigreeCouple nestedCouple = GetCoupleFromLR(model, child, spouse);
                        if (nestedCouple != null)
                        {
                            MoveChildren(dx / 2, nestedCouple, model);
                        }
                    }
                }
            }
        }
Exemplo n.º 6
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++;
                        }
                    }
                }
            };
        }