示例#1
0
        public System.Drawing.Bitmap CropImageRGB24(System.Drawing.Bitmap BitmapSrc)
        {
            try
            {
                // Create BitmapDst
                System.Drawing.Bitmap BitmapDst = new System.Drawing.Bitmap(Width, Height, System.Drawing.Imaging.PixelFormat.Format24bppRgb);

                // Convert to BitmapData
                BitmapData DataSrc = BitmapSrc.LockBits(new System.Drawing.Rectangle(0, 0, BitmapSrc.Width, BitmapSrc.Height), ImageLockMode.ReadWrite, BitmapSrc.PixelFormat);
                BitmapData DataDst = BitmapDst.LockBits(new System.Drawing.Rectangle(0, 0, BitmapDst.Width, BitmapDst.Height), ImageLockMode.ReadWrite, BitmapDst.PixelFormat);

                // 필요 요소 정의
                byte   bitsPerPixel = GetBitsPerPixel(BitmapSrc.PixelFormat);
                int    SizeSrc      = DataSrc.Stride * DataSrc.Height;
                int    SizeDst      = DataDst.Stride * DataDst.Height;
                byte[] ArraySrc     = new byte[SizeSrc];
                byte[] ArrayDst     = new byte[SizeDst];

                // Data copy from DataSrc to ArraySrc[]
                System.Runtime.InteropServices.Marshal.Copy(DataSrc.Scan0, ArraySrc, 0, SizeSrc); //  Marshal.Copy로 memcopy마냥 쓸 수 있구먼

                // ArrayDst[] 채우기
                for (int j = 0; j < Height; j++)
                {
                    for (int i = 0; i < Width; i++)
                    {
                        // Pose Matrix (회전 후 이동)
                        fPoint point = PoseMatrix(i, j, LeftTopX, LeftTopY, Angle, Width, Height);
                        int    srcx  = (int)point.x;
                        int    srcy  = (int)point.y;

                        // srcx와 srcy가 소스 밖의 점이면 0으로 넣자
                        if (srcx >= 0 && srcx <= BitmapSrc.Width && srcy >= 0 && srcy <= BitmapSrc.Height)
                        {
                            ArrayDst[i * 3 + 0 + j * DataDst.Stride] = ArraySrc[srcx * 3 + 0 + srcy * DataSrc.Stride];
                            ArrayDst[i * 3 + 1 + j * DataDst.Stride] = ArraySrc[srcx * 3 + 1 + srcy * DataSrc.Stride];
                            ArrayDst[i * 3 + 2 + j * DataDst.Stride] = ArraySrc[srcx * 3 + 2 + srcy * DataSrc.Stride];
                        }
                        else
                        {
                            ArrayDst[i * 3 + 0 + j * DataDst.Stride] = 0;
                            ArrayDst[i * 3 + 1 + j * DataDst.Stride] = 0;
                            ArrayDst[i * 3 + 2 + j * DataDst.Stride] = 0;
                        }
                    }
                }

                // Array에서 BitmapData로 Copy
                System.Runtime.InteropServices.Marshal.Copy(ArrayDst, 0, DataDst.Scan0, ArrayDst.Length);

                BitmapSrc.UnlockBits(DataSrc);
                BitmapDst.UnlockBits(DataDst);

                return(BitmapDst);
            }
            catch (Exception)
            {
                throw;
            }
        }
示例#2
0
        public static fPoint OperateDict(Dictionary <fPoint, long> dct, fPoint aproxPoint)
        {
            long minX = aproxPoint.X + -20;
            long minY = aproxPoint.Y + -20;
            long minZ = aproxPoint.Z + -20;
            long maxX = aproxPoint.X + (20);
            long maxY = aproxPoint.Y + (20);
            long maxZ = aproxPoint.Z + (20);

            long   maxBois = 0;
            fPoint lePoint = new fPoint(0, 0, 0);

            for (long i = minX; i < maxX + 1; i++)
            {
                for (long j = minY; j < maxY + 1; j++)
                {
                    for (long k = minZ; k < maxZ + 1; k++)
                    {
                        int currBois = dct.Where(r => ManhattanDist(r.Key, new fPoint(i, j, k)) <= r.Value).Count();
                        if (currBois > maxBois)
                        {
                            maxBois = currBois;
                            lePoint = new fPoint(i, j, k);
                        }
                    }
                }
            }
            return(lePoint);
        }
示例#3
0
 public Ball(fPoint pos, fVector vector, bool beep) : this(pos, vector)
 {
     // Initializes the vector of the ball if it is 0
     if (this.vector.x == 0 && this.vector.y == 0)
     {
         this.vector = fVector.getRandom();
     }
 }
        public List <FlatWithPositions> GetFlatBetweenZY(int z, int y)
        {
            var result = new List <FlatWithPositions>();
            var p      = new fPoint(z * multiplicator, y * multiplicator);

            foreach (var flat in flats)
            {
                bool b = false;
                if (flat.Points.Count() == 4)
                {
                    var v1 = vertices[flat.Points[0].VertexId - 1];
                    var v2 = vertices[flat.Points[1].VertexId - 1];
                    var v3 = vertices[flat.Points[2].VertexId - 1];
                    var v4 = vertices[flat.Points[3].VertexId - 1];

                    b = PointInTriangle(p,
                                        new fPoint(v1.Z, v1.Y),
                                        new fPoint(v2.Z, v2.Y),
                                        new fPoint(v3.Z, v3.Y)
                                        ) &&
                        PointInTriangle(p,
                                        new fPoint(v3.Z, v3.Y),
                                        new fPoint(v4.Z, v4.Y),
                                        new fPoint(v1.Z, v1.Y)
                                        );
                }
                else if (flat.Points.Count() == 3)
                {
                    var v1 = vertices[flat.Points[0].VertexId - 1];
                    var v2 = vertices[flat.Points[1].VertexId - 1];
                    var v3 = vertices[flat.Points[2].VertexId - 1];
                    b = PointInTriangle(p,
                                        new fPoint(v1.Z, v1.Y),
                                        new fPoint(v2.Z, v2.Y),
                                        new fPoint(v3.Z, v3.Y)
                                        );
                }
                if (b)
                {
                    var f = new FlatWithPositions();
                    f.FlatId = flats.IndexOf(flat);
                    foreach (var posi in flat.Points)
                    {
                        var vert = vertices[posi.VertexId - 1];
                        f.Positions.Add(new Position3D
                        {
                            X = vert.X / multiplicator,
                            Y = vert.Y / multiplicator * -1.0f,
                            Z = vert.Z / multiplicator,
                        });
                    }
                    result.Add(f);
                }
            }

            return(result);
        }
示例#5
0
 public Ball(fPoint pos, fVector vector)
 {
     this.pos    = pos;
     this.vector = vector;
     // Initializes the vector of the ball if it is 0
     if (this.vector.x == 0 && this.vector.y == 0)
     {
         this.vector = fVector.getRandom();
     }
 }
        bool PointInTriangle(fPoint pt, fPoint v1, fPoint v2, fPoint v3)
        {
            float d1, d2, d3;
            bool  has_neg, has_pos;

            d1 = sign(pt, v1, v2);
            d2 = sign(pt, v2, v3);
            d3 = sign(pt, v3, v1);

            has_neg = (d1 < 0) || (d2 < 0) || (d3 < 0);
            has_pos = (d1 > 0) || (d2 > 0) || (d3 > 0);

            return(!(has_neg && has_pos));
        }
示例#7
0
        //在鼠标按下的时候触发的事件
        public void DrawStart()
        {
            fPoint currentPoint = new fPoint(fx, fy);

            switch (selectedTool)
            {
            case Tools.pointer:
                break;

            //橡皮擦为白色的50宽度的铅笔
            case Tools.pen:
            case Tools.eraser:
                pointQueue.Enqueue(currentPoint);
                gl.Begin(OpenGL.GL_POINTS);
                {
                    gl.Vertex(fx, fy, 0f);
                }
                gl.End();
                gl.Flush();
                break;

            case Tools.line:
                pointQueue.Enqueue(currentPoint);
                //gl.genbuffers(1, buffers);
                //gl.bindbuffer(buffers[0], opengl.gl_color_buffer_bit);
                break;

            case Tools.circle:
            case Tools.rec:
                pointQueue.Enqueue(currentPoint);
                break;

            case Tools.poly:
                if (pointQueue.Count != 0)
                {
                    gl.Begin(OpenGL.GL_LINES);
                    {
                        gl.Vertex(currentPoint.fx, currentPoint.fy, 0f);
                        gl.Vertex(pointQueue.Peek().fx, pointQueue.Peek().fy);
                    }
                    gl.End();
                    pointQueue.Clear();
                }
                break;
            }
            isDrawing = true;
        }
示例#8
0
        public static Dictionary <fPoint, long> reduceDict(int factor)
        {
            Dictionary <fPoint, long> dctReturn = new Dictionary <fPoint, long>();

            foreach (var bot in dctNanoBots)
            {
                long   newCordX    = bot.Key.X / factor;
                long   newCordY    = bot.Key.Y / factor;
                long   newCordZ    = bot.Key.Z / factor;
                long   val         = bot.Value / factor;
                fPoint simplePoint = new fPoint(newCordX, newCordY, newCordZ);
                if (dctReturn.ContainsKey(simplePoint) == false)
                {
                    dctReturn.Add(simplePoint, val);
                }
            }
            return(dctReturn);
        }
示例#9
0
        // 회전 And 이동 매트릭스 테스트
        static fPoint PoseMatrix(float Model_x, float Model_y, float LeftTopX, float LeftTopY, float Degree, int width, int height)
        {
            try
            {
                // 각도를 라디안으로 변환
                double Radian = Degree * Math.PI / 180;
                float  Cos    = (float)Math.Cos(Radian);
                float  Sin    = (float)Math.Sin(Radian);

                // 1. 배열 만들기
                float[] PoseArray = new float[] {
                    Cos, -Sin, LeftTopX + width / 2,
                    Sin, Cos, LeftTopY + height / 2,
                    0, 0, 1
                };

                float[] PointArray = new float[] {
                    Model_x - width / 2,
                    Model_y - height / 2,
                    1
                };

                // 2. 배열로 Mat 만들기
                Mat PoseMat  = new Mat(3, 3, MatType.CV_32FC1, PoseArray);
                Mat PointMat = new Mat(3, 1, MatType.CV_32FC1, PointArray);

                // 3. 계산하기
                Mat     PosePoint = PoseMat * PointMat;
                float[] Result    = new float[3 * 1];
                PosePoint.GetArray(0, 0, Result);

                fPoint fpoint = new fPoint();
                fpoint.x = Result[0]; // x좌표
                fpoint.y = Result[1]; // y좌표

                return(fpoint);
            }
            catch (Exception)
            {
                throw;
            }
        }
        }//fillSelection()

        #endregion

        /// <summary>
        /// Returns true if the point falls on the rotate-marker of the passed shape; otherwise false.
        /// WARNING: Makes excessive use of hardcoded numbers.
        /// </summary>
        /// <param name="potentialShapes"></param>
        /// <returns></returns>
        private bool onRotateMarker(PowerPoint.Shape testShape, fPoint cursor)
        {
            float hDisp  = 0;  // the horizontal displacement from the center of the shape
            float vDisp  = 15; // the height above the top of the bounding box that the center of the marker is.
            float margin = 8;  // the margin (as radius, but like a square) around the center of the marker that we will accept hits on.

            // the coords (unrotated) of the marker's center.
            fPoint markCenter = new fPoint(testShape.Left + (testShape.Width / 2) + hDisp, testShape.Top - vDisp);

            // get the coords of the point
            fPoint rotCursor = rotatePointWithShape(cursor, testShape);

            //FIXME TEST DEBUG -- adds a shape to the (unrotated) location of where it thinks the marker is
            //pptController.addShapeToCurrSlide(MsoAutoShapeType.msoShapeRectangle, markCenter.x - margin, markCenter.y - margin, margin * 2, margin * 2);


            // see if they're close
            if ((Math.Abs(rotCursor.x - markCenter.x) <= margin) && (Math.Abs(rotCursor.y - markCenter.y) <= margin))
            {
                return(true);
            }

            return(false);
        }
示例#11
0
        public static void Run()
        {
            string[] linesInput = File.ReadAllLines(Util.ReadFromInputFolder(23));
            foreach (string line in linesInput)
            {
                string[] posCoords      = line.Between("<", ">").Split(',');
                long     signalStrength = Convert.ToInt64(line.Between("r=").Trim());
                long     xPoint         = Convert.ToInt64(posCoords[0]);
                long     yPoint         = Convert.ToInt64(posCoords[1]);
                long     zPoint         = Convert.ToInt64(posCoords[2]);
                fPoint   BotPosition    = new fPoint(xPoint, yPoint, zPoint);
                dctNanoBots.Add(BotPosition, signalStrength);
            }

            var strongestNano = dctNanoBots.OrderByDescending(r => r.Value).First();

            Console.WriteLine("Part 1: " + dctNanoBots.Where(r => ManhattanDist(r.Key, strongestNano.Key) <= strongestNano.Value).Count());
            Console.WriteLine("Loading part 2, should take 1 minute");

            // Reduces the lookout on the points to make complexity manageable
            // Finds best match for this small region
            // Amplifies the result to set it up for the next factor
            fPoint lePoint = new fPoint();

            for (int factor = 10000000; factor >= 1; factor /= 10)
            {
                lePoint    = OperateDict(reduceDict(factor), lePoint);
                lePoint.X *= 10;
                lePoint.Y *= 10;
                lePoint.Z *= 10;
            }
            string answer = ManhattanDist(new fPoint(0, 0, 0), lePoint).ToString();

            answer = answer.Remove(answer.Length - 1); //remove last character for the last extra computation
            Console.WriteLine("Part 2: " + answer);
        }
示例#12
0
 public static long ManhattanDist(fPoint a, fPoint b)
 {
     return(Math.Abs(a.X - b.X) + Math.Abs(a.Y - b.Y) + Math.Abs(a.Z - b.Z));
 }
示例#13
0
        /// <summary>
        /// LoadNPCSpawn
        /// </summary>
        private static void LoadMonsterSpawn()
        {
            bool l_bIsReturn = false;
            Session l_Session = new Session( BaseDatabase.Domain );
            l_Session.BeginTransaction();
            {
                do
                {
                    //////////////////////////////////////////////////////////////////////////
                    // 获取刷怪点(怪物)信息

                    Query l_QuerySpawnMonsters = new Query( l_Session, "Select SpawnMonsters instances" );
                    QueryResult l_SpawnMonstersResult = l_QuerySpawnMonsters.Execute();

                    if ( l_SpawnMonstersResult == null )
                    {
                        Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_SpawnMonstersResult == null error!" );

                        l_bIsReturn = true;
                        break;
                    }

                    for ( int iIndex = 0; iIndex < l_SpawnMonstersResult.Count; iIndex++ )
                    {
                        SpawnMonsters l_SpawnMonster = l_SpawnMonstersResult[iIndex] as SpawnMonsters;
                        if ( l_SpawnMonster == null )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_SpawnMonster == null error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        ConstructorInfo l_ConstructorInfo = s_ROSEMobilePool[l_SpawnMonster.MobileGUID];
                        if ( l_ConstructorInfo == null )
                        {
                            Debug.WriteLine( string.Format( "Program.LoadMonsterSpawn(...) - l_ConstructorInfo == null error(SpawnMonsters.SpawnGuid = {0})!", l_SpawnMonster.SpawnGuid ) );

                            l_bIsReturn = true;
                            break;
                        }

                        ROSEMobile l_ROSEMobile = l_ConstructorInfo.Invoke( null ) as ROSEMobile;
                        if ( l_ROSEMobile == null )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_ROSEMobile == null error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        Regex l_Regex = new Regex( @"(\d+)+", RegexOptions.Compiled );

                        // 分析 Points "3|5000,5000|5100,5000|5000,5100"
                        MatchCollection l_MatchCollectionPoints = l_Regex.Matches( l_SpawnMonster.Points );
                        if ( l_MatchCollectionPoints == null )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_MatchCollectionPoints == null error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        if ( l_MatchCollectionPoints.Count < 1 )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_MatchCollectionPoints.Count < 1 error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        Match l_MatchPointCount = l_MatchCollectionPoints[0];
                        Group l_GroupPointCount = l_MatchPointCount.Groups[1];

                        int l_iPointCount = -1;
                        Int32.TryParse( l_GroupPointCount.ToString(), out l_iPointCount );

                        if ( l_iPointCount < 0 )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_iPointCount < 0 error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        if ( l_MatchCollectionPoints.Count != ( l_iPointCount * 2 + 1 ) )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_MatchCollectionPoints.Count != ( l_iPointCount * 2 + 1 ) error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        List<fPoint> l_PointList = new List<fPoint>();
                        for ( int iIndex2 = 1; iIndex2 < l_MatchCollectionPoints.Count; ++iIndex2 )
                        {
                            Match l_MatchX = l_MatchCollectionPoints[iIndex2];
                            Group l_GroupX = l_MatchX.Groups[1];

                            int l_iResultX = 0;
                            Int32.TryParse( l_GroupX.ToString(), out l_iResultX );

                            Match l_MatchY = l_MatchCollectionPoints[++iIndex2];
                            Group l_GroupY = l_MatchY.Groups[1];

                            int l_iResultY = 0;
                            Int32.TryParse( l_GroupY.ToString(), out l_iResultY );

                            fPoint l_Point = new fPoint();
                            l_Point.x = l_iResultX;
                            l_Point.y = l_iResultY;

                            l_PointList.Add( l_Point );
                        }

                        fPoint l_RandPoint = RandInPoly( l_PointList.ToArray() );

                        l_ROSEMobile.X = (int)l_RandPoint.x;
                        l_ROSEMobile.Y = (int)l_RandPoint.y;

                        BaseMap l_BaseMap = s_BaseWorld.GetMap( l_SpawnMonster.MapID );
                        if ( l_BaseMap == null )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_BaseMap == null error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        //l_BaseMap.OnEnter( l_ROSEMobile );
                    }

                    if ( l_bIsReturn == true )
                        break;

                    //////////////////////////////////////////////////////////////////////////
                    // 获取刷怪点(NPC)信息

                    Query l_QuerySpawnNPCs = new Query( l_Session, "Select SpawnNPCs instances" );
                    QueryResult l_SpawnNPCsResult = l_QuerySpawnNPCs.Execute();

                    if ( l_SpawnNPCsResult == null )
                    {
                        Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_SpawnNPCsResult == null error!" );

                        l_bIsReturn = true;
                        break;
                    }

                    for ( int iIndex = 0; iIndex < l_SpawnNPCsResult.Count; iIndex++ )
                    {
                        SpawnNPCs l_SpawnNPCs = l_SpawnNPCsResult[iIndex] as SpawnNPCs;
                        if ( l_SpawnNPCs == null )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_SpawnNPCs == null error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        ConstructorInfo l_ConstructorInfo = s_ROSEMobilePool[l_SpawnNPCs.NPCGuid];
                        if ( l_ConstructorInfo == null )
                        {
                            Debug.WriteLine( string.Format( "Program.LoadMonsterSpawn(...) - l_ConstructorInfo == null error(SpawnNPCs.SpawnGuid = {0})!", l_SpawnNPCs.SpawnGuid ) );

                            l_bIsReturn = true;
                            break;
                        }

                        ROSEMobile l_ROSEMobile = l_ConstructorInfo.Invoke( null ) as ROSEMobile;
                        if ( l_ROSEMobile == null )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_ROSEMobile == null error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        l_ROSEMobile.X = (int)l_SpawnNPCs.PositionX;
                        l_ROSEMobile.Y = (int)l_SpawnNPCs.PositionY;
                        //l_ROSEMobile.Direction = l_SpawnNPCs.Direction;

                        BaseMap l_BaseMap = s_BaseWorld.GetMap( l_SpawnNPCs.MapID );
                        if ( l_BaseMap == null )
                        {
                            Debug.WriteLine( "Program.LoadMonsterSpawn(...) - l_BaseMap == null error!" );

                            l_bIsReturn = true;
                            break;
                        }

                        //l_BaseMap.OnEnter( l_ROSEMobile );
                    }
                } while ( false );
            }
            l_Session.Commit();

            if ( l_bIsReturn == true )
                throw new Exception( "读取刷怪点数据 错误!" );

            LOGs.WriteLine( LogMessageType.MSG_INFO, "信息: 刷怪点数据读取完成!" );
        }
示例#14
0
 float sign(fPoint p1, fPoint p2, fPoint p3)
 {
     return((p1.x - p3.x) * (p2.y - p3.y) - (p2.x - p3.x) * (p1.y - p3.y));
 }
示例#15
0
        /// <summary>
        /// 给出在多边形内的一个随机点
        /// </summary>
        /// <param name="point">多边形的各个点</param>
        /// <param name="pointCount">多边形点数</param>
        /// <returns>多边形内的一个随机点</returns>
        private static fPoint RandInPoly( fPoint[] point )
        {
            // 多边形内三角形数(以第一个点为公共点)
            int l_iTriangleCount = point.Length - 2;

            // 多边形内三角形的逐步累计的面积
            float[] l_Areas = new float[l_iTriangleCount];

            // 多边形的总共面积
            float l_fTotalArea = 0.0f;
            for ( int iIndex = 0; iIndex < l_iTriangleCount; iIndex++ )
            {
                l_fTotalArea += AreaOfTriangle( point[0], point[iIndex + 1], point[iIndex + 2] );
                l_Areas[iIndex] = l_fTotalArea;
            }

            float l_fRandArea = 0.0f;
            do
            {
                l_fRandArea = (float)Utility.RandomDouble() * l_fTotalArea;
            } while ( l_fRandArea == 0.0f );

            int l_iIndex = 0;
            for ( l_iIndex = 0; l_iIndex < l_iTriangleCount; l_iIndex++ )
            {
                if ( l_fRandArea <= l_Areas[l_iIndex] )
                    break;
            }

            return RandInTriangle( point[0], point[l_iIndex + 1], point[l_iIndex + 2] );
        }
        /// <summary>
        /// when shapes are stacked in layers, it's difficult to access the shapes hidden under the
        /// first item. SelectNext enables the user to access those objects with a single tap - it
        /// cycles through all the shapes that fall under this mouseDown.
        /// TODO FIXME: right now, if other gestures -- for example, moving or deleting shapes -- happen between
        /// calls to this method, we may try to access shapes that are no longer under the cursor or perhaps
        /// now nonexistant.
        /// </summary>
        /// <param name="x">x coordinate</param>
        /// <param name="y">y coordinate</param>
        /// <returns>the Shape to be selected</returns>
        internal PowerPoint.Shape selectNext(fPoint p, bool doSelect)
        {
            // if we tapped on the same point the last time we tapped (with small margin), just go through the list and select the next thing
            //TODO FIXME - don't hardcode the margin in
            if (p.isNear(lastSelectedPoint, 2))
            {
                // if it's empty, clear selection
                if (shapesAtCurrentPoint.Count == 0)
                {
                    if (doSelect)
                    {
                        selectShape(null, true);
                    }
                    return(null);
                }
                //then, if we've decremented past the end of layeredShapeCounter, loop around
                if (layeredShapeCounter < 0)
                {
                    layeredShapeCounter = shapesAtCurrentPoint.Count - 1;
                }
                // then, select the shape at the counter and decrement for next time
                if (doSelect)
                {
                    selectShape(shapesAtCurrentPoint[layeredShapeCounter], false);
                }
                layeredShapeCounter--;
                return(shapesAtCurrentPoint[layeredShapeCounter]);
            }
            // remember what point we just tapped at
            lastSelectedPoint = p;
            // Reset the list of shapes at the tapped point
            shapesAtCurrentPoint.Clear();
            // get all the shapes
            List <PowerPoint.Shape> totalShapes = pptController.allShapes();

            // List<PowerPoint.Shape> choices = new List<PowerPoint.Shape>(); // to store possible candidates

            // go through each shape and add it to the list if it's there
            foreach (PowerPoint.Shape currentShape in totalShapes)
            {
                if (pptController.pointOnShape(p, currentShape))
                {
                    shapesAtCurrentPoint.Add(currentShape);
                }
            }
            layeredShapeCounter = shapesAtCurrentPoint.Count - 1;

            // # of Shapes: 0 = clear selection
            //            : 1 = add it to selection
            //            : >1= add (last added) to selection and move counter to previous one
            PowerPoint.Shape shape;
            if (layeredShapeCounter == -1)
            {
                shape = null;
                if (doSelect)
                {
                    selectShape(null, true);
                }
                setFeedback("No object selected - please tap on top of a valid object");
            }
            else
            {
                shape = shapesAtCurrentPoint[layeredShapeCounter];
                if (doSelect)
                {
                    selectShape(shape, false);
                }
                layeredShapeCounter--; //and decrement the counter
                // DEBUG FEEDBACK FIXME
                // setFeedback("Object selected; w=" + shape.Width.ToString() + " h=" + shape.Height.ToString() + " r=" + shape.Rotation.ToString() +
                // " hf=" + shape.HorizontalFlip.ToString() + " vf=" + shape.VerticalFlip.ToString() + layeredShapeCounter);
            }

            // call up an button to display recognition alternatives of that particular textbox
            // set up such that regardless of input doSelect, a textbox will be selected if clicked
            if (shape.Type == MsoShapeType.msoTextBox)
            {
                displayButton(shape);
            }

            return(shape);
        }
示例#17
0
 //先介绍一下三维中的两点之间距离之式,和二维的几乎一样:d = sqrt((x0-x1)^2 + (y0-y1)^2 + (z0-z1)^2)
 //
 //再介绍叉乘,中心内容!叉乘在定义上有:两个向量进行叉乘得到的是一个向量,方向垂直于这两个向量构成的平面,大小等于这两个向量组成的平行四边形的面积.
 //
 //在直角座标系[O;i,j,k]中,i、j、k分别为X轴、Y轴、Z轴上向量的单位向量.设P0(0,0,0),P1(x1,y1,z1),P2(x2,y2,z2).因为是从原点出发,所以向量P0P1可简记为P1,向量P0P2可简记为P2.依定义有:
 //
 //            |i  j  k |
 //P1×P2   =  |x1 y1 z1| 
 //            |x2 y2 z2|
 //
 //展开,得到:
 //上式     = iy1z2 + jz1x2 + kx1y2 - ky1x2 - jx1z2 - iz1y2 
 //         = (y1z2 - y2z1)i + (x2z1 - x1z2)j + (x1y2 - x2y1)k
 //
 //按规定,有:单位向量的模为1.可得叉积的模为:
 //|P1×P2| = y1z2 - y2z1 + x2z1 - x1z2 + x1y2 - x2y1
 //         = (y1z2 + x2z1 + x1y2) - (y2z1 + x1z2 + x2y1)
 //
 //开始正式内容.我们设三角形的三个顶点为A(x0,y0,z0),B(x1,y1,z1),C(x2,y2,z2).我们将三角形的两条边AB和AC看成是向量.然后,我们以A为原点,进行坐标平移,得到向量B(x1-x0,y1-y0,z1-z0),向量C(x2-x0,y2-y0,z2-z0).
 //
 //①在三维的情况下,直接代入公式,可得向量B和向量C叉乘结果的模为:
 //|B×C|   = ((y1-y0)*(z2-z0) + (z1-z0)*(x2-x0) + (x1-x0)*(y2-y0)) - ((y2-y0)*(z1-z0) + (z2-z0)*(x1-x0) + (x2-x0)*(y1-y0))
 //           |  1     1     1  |
 //         = |x1-x0 y1-y0 z1-z0|
 //           |x2-x0 y2-y0 z2-z0|
 //它的一半即为所要求的三角形面积S.
 //
 //还有一种比较简单的写法.将向量AB和AC平移至原点后,设向量B为(x1,y1,z1),向量C为(x2,y2,z2),则他们的叉乘所得向量P为(x,y,z),其中:
 //    |y1 z1|     |z1 x1|     |x1 y1|
 //x = |     | y = |     | z = |     |
 //    |y2 z2|     |z2 x2|     |x2 y2|
 //然后用三维中的两点之间距离公式,求出(x,y,z)与(0,0,0)的距离,即为向量P的模,它的一半就是所要求的面积了.
 //以上公式都很好记:x分量由y,z分量组成,y分量由z,x分量组成,z分量由x,y分量组成,恰好是循环的.坐标平移一下就好了.
 //
 //②在二维的情况下,我们可以取z = 0这个平面,即令z1 = z2 = 0,且
 //|P1×P2| = x1y2 - x2y1
 //           |x1 y1|  
 //         = |     |
 //           |x2 y2|
 //所以:
 //|B×C| = (x1-x0)*(y2-y0)-(x2-x0)*(y1-y0)
 //         |x1-x0 y1-y0|
 //       = |           |
 //         |x2-x0 y2-y0|
 //它的一半即为所要求的三角形的面积S.
 //
 //注意,用行列式求出来的面积是带符号的.如果A,B,C是按顺时针方向给出,则S为负;按逆时针方向给出,则S为正.
 //以二维的情况为例,三维亦同: 
 //
 //A(0,0) B(0,1) C(1,0) (A,B,C按顺时针方向给出)
 //S = ((x1-x0)*(y2-y0)-(x2-x0)*(y1-y0))/2;
 //  = ((0 - 0)*(0 - 0)-(1 - 0)*(1 - 0))/2
 //  = -0.5
 //
 //A(1,0) B(0,1) C(0,0) (A,B,C按逆时针方向给出)
 //S = ((x1-x0)*(y2-y0)-(x2-x0)*(y1-y0))/2;
 //  = ((0 - 1)*(0 - 0)-(0 - 1)*(1 - 0))/2
 //  = 0.5
 //
 //如果你不需要符号的话,再求一下绝对值就好了.这样也不用去管给出的点的顺序了.
 //以上是利用叉乘.其实还有一招,那就是海伦公式:
 //利用两点之间距离公式,求出三角形的三边长a,b,c后,令p = (a+b+c)/2.再套入以下公式就可以求出三角形的面积S :
 //S = sqrt(p*(p-a)*(p-b)*(p-c))
 //看起来好像比上面的都要简单…… -.-b 各位看客不要打我!
 //推荐:在二维的时候使用叉乘公式,三维的时候使用海伦公式~~~不过如果是需要符号的情况时,就只能使用行列式的计算公式了.
 /// <summary>
 /// 给出三角形的面积
 /// </summary>
 /// <param name="point1"></param>
 /// <param name="point2"></param>
 /// <param name="point3"></param>
 /// <returns></returns>
 private static float AreaOfTriangle( fPoint point0, fPoint point1, fPoint point2 )
 {
     return Math.Abs( ( ( point1.x - point0.x ) * ( point2.y - point0.y ) - ( point2.x - point0.x ) * ( point1.y - point0.y ) ) / 2 ) ;
 }
示例#18
0
        //在鼠标抬起时触发的事件
        //通过读取 pointQueue 内的上一个点的数据连线
        public void DrawEnd()
        {
            isDrawing = false;
            switch (selectedTool)
            {
            case Tools.pointer:
                break;

            case Tools.pen:
            case Tools.eraser:
                pointQueue.Clear();
                break;

            case Tools.line:
                gl.Begin(OpenGL.GL_LINES);
                {
                    gl.Vertex(fx, fy, 0f);
                    gl.Vertex(pointQueue.Peek().fx, pointQueue.Peek().fy, 0f);
                }
                pointQueue.Clear();
                gl.End();
                break;

            case Tools.circle:
                //使用参数函数 x = Acos; y = Bsin画椭圆
                double lenA   = Math.Abs(fx - pointQueue.Peek().fx) / 2.0;
                double lenB   = Math.Abs(fy - pointQueue.Peek().fy) / 2.0;
                fPoint center = new fPoint((fx + pointQueue.Peek().fx) / 2.0, (fy + pointQueue.Peek().fy) / 2.0);
                int    n      = 90;    //精度,以n边的多边形代替椭圆
                gl.Begin(OpenGL.GL_POLYGON);
                {
                    for (double alpha = 0; alpha < Math.PI * 2; alpha += Math.PI / n)
                    {
                        gl.Vertex(center.fx + Math.Cos(alpha) * lenA, center.fy + Math.Sin(alpha) * lenB, 0f);
                    }
                }
                gl.End();
                pointQueue.Clear();
                break;

            case Tools.rec:
                gl.Begin(OpenGL.GL_POLYGON);
                {
                    gl.Vertex(fx, fy, 0f);
                    gl.Vertex(fx, pointQueue.Peek().fy, 0f);
                    gl.Vertex(pointQueue.Peek().fx, pointQueue.Peek().fy, 0f);
                    gl.Vertex(pointQueue.Peek().fx, fy, 0f);
                }
                gl.End();
                pointQueue.Clear();
                break;

            case Tools.poly:
                //检测是否刚刚双击
                if (!toClearPoly)
                {
                    pointQueue.Enqueue(new fPoint(fx, fy));
                }
                else
                {
                    pointQueue.Clear();
                    toClearPoly = false;
                }
                break;
            }
        }
示例#19
0
        /// <summary>
        /// 判断点point是否是三角形内 point0,point1,point2为三角形的三个顶点
        /// </summary>
        /// <param name="point0"></param>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        private static bool PointInTriangle( fPoint point0, fPoint point1, fPoint point2, fPoint point )
        {
            float iReturn0 = VectorMultiply( point0, point, point1 );
            float iReturn1 = VectorMultiply( point1, point, point2 );
            float iReturn2 = VectorMultiply( point2, point, point0 );

            if ( iReturn0 * iReturn1 * iReturn2 == 0 )
                return false;

            if ( ( iReturn0 > 0 && iReturn1 > 0 && iReturn2 > 0 ) || ( iReturn0 < 0 && iReturn1 < 0 && iReturn2 < 0 ) )
                return true;

            return false;
        }   
示例#20
0
 /// <summary>
 /// 判断三点是否共线函数
 /// </summary>
 /// <param name="point0"></param>
 /// <param name="point1"></param>
 /// <param name="point2"></param>
 /// <returns></returns>
 private static bool PointOnSameLine( fPoint point0, fPoint point1, fPoint point2 )
 {
     return ( VectorMultiply( point0, point1, point2 ) == 0 );
 }
示例#21
0
        //功能: 用户输入4个坐标(平面坐标系x轴正方向向左,y正方向向上),判断前3个坐标是否可以作为三角形的3个顶点;   
        //           如果能,同时判断第四个坐标是否在这个三角形内   (不包括在边上和顶点上) 
        //
        //说明: 程序中涉及到两个函数PoOnSameLine和PoRelative.   
        //      其中函数PoOnSameLine是用来判断三点是否共线,函数PoRelative返回点与直线的关系,   
        //           两个函数都要用到向量叉积公式:   
        //           向量A和向量B的叉积是一个向量,记作A×B,方向可以用右用定则得出,其模|A×B| = |A||B|sin& (&是A与B的夹角)   
        //                                       | i , j , k  |     
        //           向量叉积的坐标表示为:A*B =  | a1, a2, a3 | (其中i,j,k分别为单位向量; A = [a1,a2,a3], B = [b1,b2,b3])   
        //                                       | b1, b2, b3 |   
        //
        //           判断三点是否共线的算法如下:   
        //           设三角形的三个顶点为A(x1,y1),B(x2,y2),和C(x3,y3),   
        //           以A为共同点分别连接B和C,得出向量AB和AC,坐标表示为 AB = (x2-x1,y2-y1), AC = (x3-x1,y3-y1)   
        //                     | x2 - x1, y2 - y1 |     
        //           AB*AC   = | x3 - x1, y3 - y1 |
        //                   = (x2 - x1)(y3 - y1) - (y2 - y1)(x3 - x1)   
        //           由|A||B|sin&=0得,如果AB×AC=0则点A,B,C在同一条直线上(共顶点A且夹角为零)   
        //
        //           判断第四个点与直线的关系算法:   
        //           设三角形按逆时针方向的三个顶点分别为A,B,C,第四个点为P,我们按逆时针方向连接ABC,得到三个向量分别为AB,BC,CA,
        //           再分别以A,B,C为顶点,连接P,得到向量AP,BP,CP,分别计算AB×AP,BC×BP,CA×CP的值,结果为三个新向量N1,N2和N3,
        //           根据N*的方向可得出点P与向量AB,BC,CA的位置关系,我们以左侧或右侧来描述   

        //           根据位置关系,对于点P,如果他同时位于向量的AB,BC和CA的同一侧(左侧或右侧)即向量N同号(不为零),则点在三角形内,
        //           否则在三角形外(如果叉乘为零则点位于向量上),该判定还可上升到凸多边形的情况.  
 
        /// <summary>
        /// 返回向量叉乘,公共点为point0   
        /// </summary>
        /// <param name="point0"></param>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        /// <returns></returns>
        private static float VectorMultiply( fPoint point0, fPoint point1, fPoint point2 )
        {
            return ( ( point1.x - point0.x ) * ( point2.y - point0.y ) - ( point2.x - point0.x ) * ( point1.y - point0.y ) );
        }
示例#22
0
        /// <summary>
        /// 给出在三角形内的一个随机点
        /// </summary>
        /// <param name="point1"></param>
        /// <param name="point2"></param>
        /// <param name="point3"></param>
        /// <returns></returns>
        private static fPoint RandInTriangle( fPoint point0, fPoint point1, fPoint point2 )
        {
            float floatA = 0.0f;
            do
            {
                floatA = (float)Utility.RandomDouble();
            } while ( floatA == 0.0f );

            float floatB = 0.0f;
            do
            {
                floatB = (float)Utility.RandomDouble();
            } while ( floatB == 0.0f || floatB + floatA >= 1.0 );

            float floatC = 1 - floatA - floatB;

            fPoint l_ReturnPoint = new fPoint();
            l_ReturnPoint.x = ( point0.x * floatA ) + ( point1.x * floatB ) + ( point2.x * floatC );
            l_ReturnPoint.y = ( point0.y * floatA ) + ( point1.y * floatB ) + ( point2.y * floatC );

            return l_ReturnPoint;
        }