예제 #1
0
        public void addNode(StrokeGroup sg)
        {
            /*
             * 1.	如果SKContextDG为空,创建关于s新节点nodeS,算法结束;
             * 2.	创建新节点nodeS,计算笔迹s与前一输入笔迹s’的输入时间差deltTime;
             * 3.	如果deltTime < ThresholdTime,将前一输入笔迹s所对应的节点的tPointer指针指向nodeS;
             * 4.	顺次遍历SKContextDG的历史节点,计算nodeS与历史节点的空间距离dist,根据dist’值判断二者之间的空间关系R;
             * 5.	如果R= ST,在两个节点之间建立空间关联链接,重复步骤4直至遍历完所有节点。
             */

            nodeIndex++;
            SKContextDGNode node = new SKContextDGNode(sg, sg.StartTime, nodeIndex);

            DGNodeList.Add(node);
            node.groupID = sg.groupID;


            double thresholdTime    = 1.2;    //TODO::阈值的确定
            double thresholdSpatial = 1000;   //TODO::阈值的确定


            //空间邻近关系建立
            double dist = -1;

            dist = distance(sg, lastNode.strokeGroup);
            if ((dist > thresholdSpatial) && (!DGHeadList.Contains(node)))
            {
                newHead(node);
            }

            foreach (SKContextDGNode preNode in DGNodeList)
            {
                if (preNode != node)
                {
                    StrokeGroup preSg = null;
                    preSg = preNode.strokeGroup;
                    dist  = distance(sg, preSg);
                    if ((dist < thresholdSpatial) && (!node.sPointer.Contains(preNode)))
                    {
                        node.sPointer.Add(preNode);
                    }
                }
            }


            //时间邻近关系建立
            double delta = (long)((TimeSpan)(sg.StartTime - lastNode.timeStamp)).TotalSeconds;

            if (delta < thresholdTime)
            {
                //时间邻近
                lastNode.tPointer = node;
            }
            else if (!DGHeadList.Contains(node))
            {
                newHead(node);
            }

            lastNode = node;
        }
예제 #2
0
 public SKContextDGNode(StrokeGroup sg, DateTime time, int nodeIndex)
 {
     strokeGroup = sg;
     timeStamp   = time;
     ID          = nodeIndex;
     tPointer    = null;
 }
예제 #3
0
 ///<summary>
 ///将group删除掉
 ///</summary>
 public void deleteGroup(StrokeGroup strokegroup)
 {
     foreach (MyStroke stroke in strokegroup.strokeList)
     {
         stroke.inkstroke.Ink.DeleteStroke(stroke.inkstroke);
         strokeList.Remove(stroke);
     }
     groupList.Remove(strokegroup);
 }
예제 #4
0
        public double distance(StrokeGroup sg1, StrokeGroup sg2)
        {
            double mindist = 10000;
            double dist;

            foreach (MyStroke stroke1 in sg1.strokeList)
            {
                foreach (MyStroke stroke2 in sg2.strokeList)
                {
                    dist = distanceStroketoStroke(stroke1, stroke2);
                    if (dist < mindist)
                    {
                        mindist = dist;
                    }
                }
            }

            return(mindist);
        }
예제 #5
0
        /// <summary>
        /// 计算group的skeleton方程 y = mx +c 
        /// 将结果m和c保存到strokegroup数据结构中
        /// </summary>
        /// <param name="group"></param>
        public void computeSkeleton(StrokeGroup group)
        {
            LinkedList<MyStroke> sts = group.strokeList;
            List<Point> ptlist = new List<Point>();
            foreach (MyStroke ms in sts)
            {
                Point[] points = ms.points;
                foreach (Point p in points)
                {
                    ptlist.Add(p);
                }
            }
            Point[] pts = ptlist.ToArray();

            double m = 0;
            double c = 0;
            double
                sumx2 = 0,
                sumx = 0,
                sumy = 0,
                sumxy = 0;

            foreach (Point p in pts)
            {
                int x = p.X, y = p.Y;
                sumx += x;
                sumy += y;
                sumx2 += x * x;
                sumxy += x * y;
            }

            m = (pts.Length * sumxy - sumx * sumy) / (pts.Length * sumx2 - sumx * sumx);
            c = (sumx2 * sumy - sumx * sumxy) / (pts.Length * sumx2 - sumx * sumx);

            group.m = m;
            group.c = c;
        }
예제 #6
0
        public void addStroke(Stroke stroke)
        {
            List <Stroke> changes   = new List <Stroke>();//需要刷新的stroke
            MyStroke      newstroke = new MyStroke(stroke);

            newstroke.setBoundingBox();                            //YHY-090412
            Sketch currentpage = sketch.currentpage.Value.content; //当前页

            ///线性测试
            if (tool.LinearityTest(newstroke) == Linearity.Line)
            {
                //新增加的stroke是直线
                ///straight-line segment fitting
                foreach (StrokeGroup strokegroup in currentpage.groupList)
                {
                    if (strokegroup.TYPE == GroupType.DEFAULT)
                    {
                        MyStroke mstroke = strokegroup.strokeList.First.Value;
                        if ((tool.DistanceTest(newstroke, mstroke) == TESTRESULT.GROUP) &&
                            (tool.AngleTest(newstroke, mstroke) == TESTRESULT.GROUP))
                        {
                            //通过了距离测试和角度测试
                            strokegroup.addStroke(newstroke);
                            drawingInk.Ink.DeleteStroke(strokegroup.Skeleton);
                            strokegroup.Skeleton = drawingInk.Ink.CreateStroke(strokegroup.SkeletonPoints);
                            strokegroup.Skeleton.DrawingAttributes = this.Skeleton_Attibute;
                            strokegroup.setBoundingBox();//YHY-090412
                            changes.Add(strokegroup.Skeleton);
                            break;
                        }
                    }
                }
                ///如果新增加的笔画没有找到组织,那么将给它单独建一个组
                if (!newstroke.isInGroup)
                {
                    //如果没有通过距离测试和角度测试
                    //Seperate Line
                    StrokeGroup sg = new StrokeGroup(GroupType.DEFAULT);
                    sketch.groupIndex++;
                    sg.groupID = sketch.groupIndex; //YHY-090413 增加一个标志
                    sg.addStroke(newstroke);
                    sg.Skeleton = drawingInk.Ink.CreateStroke(sg.SkeletonPoints);
                    sg.Skeleton.DrawingAttributes = this.Skeleton_Attibute;
                    //YHY-090410
                    sg.GRAPH = Graphic.Line;
                    sg.setBoundingBox();
                    sg.geometry = new G_Line(newstroke.startPoint, newstroke.endPoint);//YHY-090415

                    currentpage.addGroup(sg);

                    //判断新加入的strokegroup代表的图元和历史图元之间的约束关系
                    refreshConstraint(sg);

                    //yhy-090409
                    //将新建的group加入到skechContextDG中去
                    if (sketch.sketchContextDG.isEmpty())
                    {
                        sketch.sketchContextDG.nodeIndex++;
                        SKContextDGNode node = new SKContextDGNode(sg, sg.StartTime, sketch.sketchContextDG.nodeIndex);
                        node.groupID = sg.groupID;
                        sketch.sketchContextDG.newHead(node);
                        sketch.sketchContextDG.firstNode = node;
                        sketch.sketchContextDG.lastNode  = node;
                    }
                    else
                    {
                        sketch.sketchContextDG.addNode(sg);
                    }
                }

                //Groupping: add curve object to strokeGroup and sketch
                //YHY-090409
                ////////////////////////////////////////////////////////////////////////////////
                //YHY-090414
                //Just for test, ReGroup
                //sketchReGroupping();
                //drawBoundingBoxtoTestGrouppingResult();
                //////////////////////////////////////////////////////////////////////////////////


                /* StrokeGroup ngroup = newstroke.group;
                 *
                 * foreach (StrokeGroup group in currentpage.groupList)
                 * {
                 *  if (group == ngroup)
                 *      continue;
                 *
                 *  if (tool.distanceP2P(ngroup.startPoint, group.startPoint) < Threshold_Distance)
                 *  {
                 *      ngroup.startPoint = group.startPoint;
                 *      ngroup.computeSkeletonFromEnds();
                 *  }
                 *  else if (tool.distanceP2P(ngroup.startPoint, group.endPoint) < Threshold_Distance)
                 *  {
                 *      ngroup.startPoint = group.endPoint;
                 *      ngroup.computeSkeletonFromEnds();
                 *  }
                 *  else if (tool.distanceP2P(ngroup.endPoint, group.startPoint) < Threshold_Distance)
                 *  {
                 *      ngroup.endPoint = group.startPoint;
                 *      ngroup.computeSkeletonFromEnds();
                 *  }
                 *  else if (tool.distanceP2P(ngroup.endPoint, group.endPoint) < Threshold_Distance)
                 *  {
                 *      ngroup.endPoint = group.endPoint;
                 *      ngroup.computeSkeletonFromEnds();
                 *  }
                 * }*/
            }

            else if (tool.LinearityTest(newstroke) == Linearity.Curve)
            {
                //如果线性测试的结果是曲线

                //TODO::ToolForStroke.circle(et al).judge function
                //YHY-090408
                //先不考虑曲线补笔等草图特效的问题,假设所有曲线相关的sketch都是单笔的
                //判断是否为circle
                bool isCircle = false;
                isCircle = tool.JudgeCircle(newstroke);

                //YHY-090410
                //创建新的group,先不考虑曲线补笔等情况
                if (!newstroke.isInGroup)
                {
                    StrokeGroup sg = new StrokeGroup(GroupType.DEFAULT);
                    sketch.groupIndex++;
                    sg.groupID = sketch.groupIndex;
                    sg.addStroke(newstroke);
                    sg.setBoundingBox();

                    if (isCircle)
                    {
                        //TODO::暂时统一都认为是圆,以后需要改成椭圆
                        sg.GRAPH = Graphic.Circle;
                        Point  p = new Point();
                        double r;
                        p.X         = sg.boundingBox.Left + sg.boundingBox.Width / 2;
                        p.Y         = sg.boundingBox.Top + sg.boundingBox.Height / 2;
                        r           = System.Math.Min(sg.boundingBox.Height, sg.boundingBox.Width) / 2;
                        sg.geometry = new G_Cricle(p, r);//YHY-090415
                    }
                    else
                    {
                        sg.GRAPH = Graphic.Curve;
                    }

                    //sg.Skeleton = inkpicture.Ink.CreateStroke(sg.SkeletonPoints); //TODO: Get curve skeleton
                    //sg.Skeleton.DrawingAttributes = this.Skeleton_Attibute;
                    currentpage.addGroup(sg);

                    //捕捉约束
                    //判断新加入的strokegroup代表的图元和历史图元之间的约束关系
                    refreshConstraint(sg);


                    //yhy-090409
                    //将新建的group加入到skechContextDG中去
                    if (sketch.sketchContextDG.isEmpty())
                    {
                        sketch.sketchContextDG.nodeIndex++;
                        SKContextDGNode node = new SKContextDGNode(sg, sg.StartTime, sketch.sketchContextDG.nodeIndex);
                        node.groupID = sg.groupID;
                        sketch.sketchContextDG.newHead(node);
                        sketch.sketchContextDG.firstNode = node;
                        sketch.sketchContextDG.lastNode  = node;
                    }
                    else
                    {
                        sketch.sketchContextDG.addNode(sg);
                    }
                }

                //Groupping: add curve object to strokeGroup and sketch
                //YHY-090408
                ////////////////////////////////////////////////////////////////////////////////
                //YHY-090414
                //Just for test, ReGroup
                //   sketchReGroupping();
                //   drawBoundingBoxtoTestGrouppingResult();
                //////////////////////////////////////////////////////////////////////////////////



                //TODO::constraint capture function
                //如果未归为prior group,则需判断新添笔迹(group)与原来笔迹的约束关系
                //YHY-090416
                //判断新添加strokegroup里的图元和其余历史图元之间的关系
            }

            currentpage.addStroke(newstroke);
            ///对纸张进行局部更新
            if (stroke != null)
            {
                inkPanel.Invalidate(tool.InkSpaceToPixelRect(inkPanel.Handle, drawingInk.Renderer, stroke.GetBoundingBox()));
                foreach (Stroke st in changes)
                {
                    inkPanel.Invalidate(tool.InkSpaceToPixelRect(inkPanel.Handle, drawingInk.Renderer, st.GetBoundingBox()));
                }
            }
        }
예제 #7
0
        public void refreshConstraint(StrokeGroup sg)
        {
            bool isL_L_Vertical     = false;
            bool isL_L_Intersect    = false;
            bool isL_L_Parallel     = false;
            bool isL_C_Tangent      = false;
            bool isL_C_Intersect    = false;
            bool isL_C_LineInCircle = false;

            //TODO::加入更多的约束关系


            if (sg.GRAPH == Graphic.Line)
            {
                G_Line geo1 = (G_Line)sg.geometry;

                foreach (SKContextDGNode nd in sketch.sketchContextDG.DGNodeList)
                {
                    Graphic type = nd.strokeGroup.GRAPH;

                    switch (type)
                    {
                    case Graphic.Line:      //L_L
                        G_Line geo2 = (G_Line)nd.strokeGroup.geometry;
                        if (geo2 != null)
                        {
                            isL_L_Vertical  = new G_L_L_Constraints().L_L_Vertical(geo1, geo2);
                            isL_L_Intersect = new G_L_L_Constraints().L_L_Intersect(geo1, geo2);
                            isL_L_Parallel  = new G_L_L_Constraints().L_L_Parallel(geo1, geo2);
                            //保存约束
                            ConstraintElement elem = new ConstraintElement();
                            elem.strokeGroup1 = sg;
                            elem.strokeGroup2 = nd.strokeGroup;
                            if (isL_L_Intersect)
                            {
                                elem.ctype = ConstraintType.Intersect;
                                sketch.m_pConsList.Add(elem);
                                // MessageBox.Show("Intersecting");
                            }
                            if (isL_L_Parallel)
                            {
                                elem.ctype = ConstraintType.Parallel;
                                sketch.m_pConsList.Add(elem);
                                //  MessageBox.Show("Parallel");
                            }
                            if (isL_L_Vertical)
                            {
                                elem.ctype = ConstraintType.Vertical;
                                sketch.m_pConsList.Add(elem);
                                //  MessageBox.Show("Vertical");
                            }
                        }
                        break;

                    case Graphic.Circle:      //L_C
                        G_Cricle geo3 = (G_Cricle)nd.strokeGroup.geometry;
                        if (geo3 != null)
                        {
                            isL_C_Tangent      = new G_L_C_Constraints().L_C_Tangent();
                            isL_C_Intersect    = new G_L_C_Constraints().L_C_Intesect(geo1, geo3);
                            isL_C_LineInCircle = new G_L_C_Constraints().L_C_LineInCircle(geo1, geo3);
                            //保存约束
                            ConstraintElement elem1 = new ConstraintElement();
                            elem1.strokeGroup1 = sg;
                            elem1.strokeGroup2 = nd.strokeGroup;
                            if (isL_C_Tangent)
                            {
                                elem1.ctype = ConstraintType.Tangent;
                                sketch.m_pConsList.Add(elem1);
                                // MessageBox.Show("Intersecting");
                            }
                            if (isL_C_Intersect)
                            {
                                elem1.ctype = ConstraintType.Intersect;
                                sketch.m_pConsList.Add(elem1);
                                //  MessageBox.Show("Parallel");
                            }
                            if (isL_C_LineInCircle)
                            {
                                elem1.ctype = ConstraintType.In;
                                sketch.m_pConsList.Add(elem1);
                                //  MessageBox.Show("Vertical");
                            }
                        }
                        break;

                    default:
                        break;
                    }
                }
            }
            else
            if (sg.GRAPH == Graphic.Circle)    //Circle
            {
                G_Cricle geo4 = (G_Cricle)sg.geometry;

                foreach (SKContextDGNode nd in sketch.sketchContextDG.DGNodeList)
                {
                    Graphic type = nd.strokeGroup.GRAPH;
                    switch (type)
                    {
                    case Graphic.Line:         //L_C
                        G_Line geo5 = (G_Line)nd.strokeGroup.geometry;
                        if (geo5 != null)
                        {
                            isL_C_Tangent      = new G_L_C_Constraints().L_C_Tangent();
                            isL_C_Intersect    = new G_L_C_Constraints().L_C_Intesect(geo5, geo4);
                            isL_C_LineInCircle = new G_L_C_Constraints().L_C_LineInCircle(geo5, geo4);
                            //保存约束
                            ConstraintElement elem1 = new ConstraintElement();
                            elem1.strokeGroup1 = sg;
                            elem1.strokeGroup2 = nd.strokeGroup;
                            if (isL_C_Tangent)
                            {
                                elem1.ctype = ConstraintType.Tangent;
                                sketch.m_pConsList.Add(elem1);
                                // MessageBox.Show("Intersecting");
                            }
                            if (isL_C_Intersect)
                            {
                                elem1.ctype = ConstraintType.Intersect;
                                sketch.m_pConsList.Add(elem1);
                                //  MessageBox.Show("Parallel");
                            }
                            if (isL_C_LineInCircle)
                            {
                                elem1.ctype = ConstraintType.In;
                                sketch.m_pConsList.Add(elem1);
                                //  MessageBox.Show("Vertical");
                            }
                        }
                        break;

                    case Graphic.Circle:         //C_C
                        break;

                    default:
                        break;
                    }
                }
            }
        }
예제 #8
0
 /// <summary>
 /// 向sketch中增加strokegroup
 /// </summary>
 /// <param name="strokegroup"></param>
 public void addGroup(StrokeGroup strokegroup)
 {
     groupList.Add(strokegroup);
 }