static void CreateBoneJointIfNeed(
     InsideEdgeLine insideEdge,
     GlyphTriangle first_p_tri,
     GlyphBoneJoint firstJoint,
     List <GlyphBone> newlyCreatedBones,
     List <GlyphBone> glyphBones)
 {
     if (insideEdge != null &&
         insideEdge.inside_joint == null)
     {
         InsideEdgeLine mainEdge = insideEdge;
         EdgeLine       nbEdge   = null;
         if (FindSameCoordEdgeLine(first_p_tri.N0, mainEdge, out nbEdge) ||
             FindSameCoordEdgeLine(first_p_tri.N1, mainEdge, out nbEdge) ||
             FindSameCoordEdgeLine(first_p_tri.N2, mainEdge, out nbEdge))
         {
             //confirm that nbEdge is INSIDE edge
             if (nbEdge.IsInside)
             {
                 GlyphBoneJoint joint = new GlyphBoneJoint((InsideEdgeLine)nbEdge, mainEdge);
                 GlyphBone      bone  = new GlyphBone(mainEdge.inside_joint, firstJoint);
                 newlyCreatedBones.Add(bone);
                 glyphBones.Add(bone);
             }
             else
             {
                 //?
             }
         }
         else
         {
             //?
         }
     }
 }
Ejemplo n.º 2
0
 /// <summary>
 /// find a perpendicular cut-point from p to bone
 /// </summary>
 /// <param name="bone"></param>
 /// <param name="p"></param>
 /// <param name="cutPoint"></param>
 /// <returns></returns>
 public static bool FindPerpendicularCutPoint(GlyphBone bone, Vector2 p, out Vector2 cutPoint)
 {
     if (bone.JointB != null)
     {
         cutPoint = FindPerpendicularCutPoint(
             bone.JointA.OriginalJointPos,
             bone.JointB.OriginalJointPos,
             p);
         //find min /max
         Vector2 min, max;
         GetMinMax(bone, out min, out max);
         return(cutPoint.X >= min.X && cutPoint.X <= max.X && cutPoint.Y >= min.Y && cutPoint.Y <= max.Y);
     }
     else
     {
         //to tip
         if (bone.TipEdge != null)
         {
             cutPoint = FindPerpendicularCutPoint(
                 bone.JointA.OriginalJointPos,
                 bone.TipEdge.GetMidPoint(),
                 p);
             Vector2 min, max;
             GetMinMax(bone, out min, out max);
             return(cutPoint.X >= min.X && cutPoint.X <= max.X && cutPoint.Y >= min.Y && cutPoint.Y <= max.Y);
         }
         else
         {
             throw new System.NotSupportedException();
         }
     }
 }
 static void CreateTipBoneIfNeed(
     InsideEdgeLine insideEdge, GlyphBoneJoint joint,
     List <GlyphBone> newlyCreatedBones, List <GlyphBone> glyphBones)
 {
     if (insideEdge != null &&
         insideEdge.inside_joint != null &&
         insideEdge.inside_joint != joint)
     {
         //create connection
         GlyphBone tipBone = new GlyphBone(insideEdge.inside_joint, joint);
         newlyCreatedBones.Add(tipBone);
         glyphBones.Add(tipBone);
     }
 }
Ejemplo n.º 4
0
 //utils for glyph bones
 public static Vector2 GetMidPoint(this GlyphBone bone)
 {
     if (bone.JointB != null)
     {
         return((bone.JointA.OriginalJointPos + bone.JointB.OriginalJointPos) / 2);
     }
     else if (bone.TipEdge != null)
     {
         Vector2 edge = bone.TipEdge.GetMidPoint();
         return((edge + bone.JointA.OriginalJointPos) / 2);
     }
     else
     {
         return(Vector2.Zero);
     }
 }
        internal void CollectOutsideEdges(List <EdgeLine> tmpEdges)
        {
            tmpEdges.Clear();
            int index = this.startIndex;

            for (int n = this.count - 1; n >= 0; --n)
            {
                GlyphBone bone = ownerCentroidLine.bones[index];
                //collect all outside edge around glyph bone
                bone.CollectOutsideEdge(tmpEdges);
                index++;
            }
            //
            if (tmpEdges.Count == 0)
            {
                return;
            }
            this.edges = tmpEdges.ToArray();
        }
Ejemplo n.º 6
0
        static void GetMinMax(GlyphBone bone, out Vector2 min, out Vector2 max)
        {
            if (bone.JointB != null)
            {
                var a_pos = bone.JointA.OriginalJointPos;
                var b_pos = bone.JointB.OriginalJointPos;

                min = Vector2.Min(a_pos, b_pos);
                max = Vector2.Max(a_pos, b_pos);
            }
            else if (bone.TipEdge != null)
            {
                var a_pos   = bone.JointA.OriginalJointPos;
                var tip_pos = bone.TipEdge.GetMidPoint();
                min = Vector2.Min(a_pos, tip_pos);
                max = Vector2.Max(a_pos, tip_pos);
            }
            else
            {
                throw new System.NotSupportedException();
            }
        }
Ejemplo n.º 7
0
 /// <summary>
 /// find all outside edge a
 /// </summary>
 /// <param name="bone"></param>
 /// <param name="outsideEdges"></param>
 /// <returns></returns>
 public static void CollectOutsideEdge(this GlyphBone bone, System.Collections.Generic.List <EdgeLine> outsideEdges)
 {
     if (bone.JointB != null)
     {
         GlyphTriangle commonTri = FindCommonTriangle(bone.JointA, bone.JointB);
         if (commonTri != null)
         {
             if (commonTri.e0.IsOutside)
             {
                 outsideEdges.Add(commonTri.e0);
             }
             if (commonTri.e1.IsOutside)
             {
                 outsideEdges.Add(commonTri.e1);
             }
             if (commonTri.e2.IsOutside)
             {
                 outsideEdges.Add(commonTri.e2);
             }
         }
     }
     else if (bone.TipEdge != null)
     {
         outsideEdges.Add(bone.TipEdge);
         EdgeLine found;
         if (ContainsEdge(bone.JointA.P_Tri, bone.TipEdge) &&
             (found = FindAnotherOutsideEdge(bone.JointA.P_Tri, bone.TipEdge)) != null)
         {
             outsideEdges.Add(found);
         }
         else if (ContainsEdge(bone.JointA.Q_Tri, bone.TipEdge) &&
                  (found = FindAnotherOutsideEdge(bone.JointA.Q_Tri, bone.TipEdge)) != null)
         {
             outsideEdges.Add(found);
         }
     }
 }
        /// <summary>
        /// apply grid box to all bones in this line
        /// </summary>
        /// <param name="gridW"></param>
        /// <param name="gridH"></param>
        public void ApplyGridBox(List <BoneGroup> boneGroups, int gridW, int gridH)
        {
            //1. apply grid box to each joint
            for (int i = _joints.Count - 1; i >= 0; --i)
            {
                _joints[i].AdjustFitXY(gridW, gridH);
            }
            //2. (re) calculate slope for all bones.
            for (int i = bones.Count - 1; i >= 0; --i)
            {
                bones[i].EvaluateSlope();
            }
            //3. re-grouping
            int       j         = bones.Count;
            BoneGroup boneGroup = new BoneGroup(this); //new group

            boneGroup.slopeKind = LineSlopeKind.Other;
            //
            float approxLen = 0;
            float ypos_sum  = 0;
            float xpos_sum  = 0;

            for (int i = 0; i < j; ++i)
            {
                GlyphBone     bone    = bones[i];
                LineSlopeKind slope   = bone.SlopeKind;
                Vector2       mid_pos = bone.GetMidPoint();

                if (slope != boneGroup.slopeKind)
                {
                    //add existing to list and create a new group
                    if (boneGroup.count > 0)
                    {
                        //add existing bone group to bone-group list
                        boneGroup.approxLength = approxLen;
                        boneGroup.avg_x        = xpos_sum / boneGroup.count;
                        boneGroup.avg_y        = ypos_sum / boneGroup.count;
                        //
                        boneGroups.Add(boneGroup);
                    }
                    //
                    boneGroup            = new BoneGroup(this);
                    boneGroup.startIndex = i;
                    boneGroup.slopeKind  = slope;
                    //
                    boneGroup.count++;
                    approxLen = bone.EvaluateFitLength(); //reset
                    //
                    xpos_sum = mid_pos.X;
                    ypos_sum = mid_pos.Y;
                }
                else
                {
                    boneGroup.count++;
                    approxLen += bone.EvaluateFitLength(); //append
                    //
                    xpos_sum += mid_pos.X;
                    ypos_sum += mid_pos.Y;
                }
            }
            //
            if (boneGroup.count > 0)
            {
                boneGroup.approxLength = approxLen;
                boneGroup.avg_x        = xpos_sum / boneGroup.count;
                boneGroup.avg_y        = ypos_sum / boneGroup.count;
                boneGroups.Add(boneGroup);
            }
        }
        /// <summary>
        /// create a set of GlyphBone
        /// </summary>
        /// <param name="newlyCreatedBones"></param>
        public void CreateBones(List <GlyphBone> newlyCreatedBones)
        {
            foreach (CentroidLine line in _lines.Values)
            {
                List <GlyphBoneJoint> jointlist = line._joints;
                //start with empty bone list
                List <GlyphBone> glyphBones = line.bones;
                int j = jointlist.Count;

                if (j == 0)
                {
                    continue;
                }
                //
                GlyphBoneJoint joint = jointlist[0]; //first
                {
                    GlyphTriangle firstTri = joint.P_Tri;
                    //test 3 edges, find edge that is inside
                    //and the joint is not the same as first_pair.BoneJoint
                    CreateTipBoneIfNeed(firstTri.e0 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                    CreateTipBoneIfNeed(firstTri.e1 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                    CreateTipBoneIfNeed(firstTri.e2 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                }

                for (int i = 0; i < j; ++i)
                {
                    //for each GlyphCentroidPair
                    //create bone that link the GlyphBoneJoint of the pair
                    joint = jointlist[i];
                    //if (joint.dbugId > 20)
                    //{
                    //}
                    if (joint.TipEdgeP != null)
                    {
                        GlyphBone tipBone = new GlyphBone(joint, joint.TipEdgeP);
                        newlyCreatedBones.Add(tipBone);
                        glyphBones.Add(tipBone);
                    }
                    //-----------------------------------------------------
                    if (i < j - 1)
                    {
                        //not the last one
                        GlyphBoneJoint nextJoint = jointlist[i + 1];
                        GlyphBone      bone      = new GlyphBone(joint, nextJoint);
                        newlyCreatedBones.Add(bone);
                        glyphBones.Add(bone);
                    }

                    if (joint.TipEdgeQ != null)
                    {
                        GlyphBone tipBone = new GlyphBone(joint, joint.TipEdgeQ);
                        newlyCreatedBones.Add(tipBone);
                        glyphBones.Add(tipBone);
                    }
                }


                //for (int i = 1; i < j; ++i)
                //{
                //    joint = jointlist[i]; //first
                //    {
                //        GlyphTriangle tri = joint.P_Tri;
                //        //test 3 edges, find edge that is inside
                //        //and the joint is not the same as first_pair.BoneJoint
                //        CreateTipBoneIfNeed(tri.e0 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                //        CreateTipBoneIfNeed(tri.e1 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                //        CreateTipBoneIfNeed(tri.e2 as InsideEdgeLine, joint, newlyCreatedBones, glyphBones);
                //    }
                //}
            }
        }
Ejemplo n.º 10
0
 protected abstract void OnDrawBone(GlyphBone bone, int boneIndex);