//============== return value ===============// // // -1 // 9 9 // ┌───────────────────────┐ // │ 1 8 4 │ // │ │ // -1 │ 5 0 7 │ -1 // │ │ // │ 2 6 3 │ // └───────────────────────┘ // 9 9 // -1 // // // Anchor Point : 10 //============================================// public int partOfSelection(float x, float y, out int cursor) { cursor = -1; if (selectedItems.Count == 0) { return(-1); } if (selectedItems.Count > 1) { return(containsInSelection(x, y) ? 0 : 9); } TActor actor = selectedItems[0]; if (currentTool == TDocument.TOOL_PUZZLE && !actor.puzzle) { return(-1); } PointF screenPos = new PointF(x, y); PointF logicalPos = currentTool != TDocument.TOOL_PUZZLE ? actor.screenToLogical(new PointF(x, y)) : actor.ownerScene().screenToLogical(new PointF(x, y)); RectangleF actorBound = actor.bound(); PointF anchorPosOnScreen = actor.logicalToScreen(new PointF(actorBound.Width * actor.anchor.X, actorBound.Height * actor.anchor.Y)); RectangleF bound; if (currentTool == TDocument.TOOL_BOUNDING) { bound = actor.interactionBound; } else if (currentTool == TDocument.TOOL_PUZZLE) { bound = actor.puzzleArea; } else { bound = actorBound; } PointF[] boundOnScreen; if (currentTool == TDocument.TOOL_BOUNDING) { boundOnScreen = actor.interactionBoundOnScreen(); } else if (currentTool == TDocument.TOOL_PUZZLE) { boundOnScreen = actor.puzzleAreaOnScreen(); } else { boundOnScreen = actor.boundOnScreen(); } int ctrl_size = 6; bool leftEdge = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[0], boundOnScreen[1]) <= ctrl_size; bool bottomEdge = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[1], boundOnScreen[2]) <= ctrl_size; bool rightEdge = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[2], boundOnScreen[3]) <= ctrl_size; bool topEdge = TUtil.distanceBetweenPointLine(screenPos, boundOnScreen[3], boundOnScreen[0]) <= ctrl_size; bool insideBound = bound.Contains(logicalPos); int first_cursor = 0; // cursor form part 5 double angle = -Math.Atan2(boundOnScreen[1].Y - boundOnScreen[0].Y, boundOnScreen[1].X - boundOnScreen[0].X) * 180 / Math.PI; if (angle < 0) { angle += 360; } first_cursor = (int)((angle + 22.5) / 45) % 4; int part = -1; if (leftEdge && topEdge) { part = 1; cursor = (first_cursor - 1) % 4; } else if (leftEdge && bottomEdge) { part = 2; cursor = (first_cursor + 1) % 4; } else if (rightEdge && bottomEdge) { part = 3; cursor = (first_cursor + 3) % 4; } else if (rightEdge && topEdge) { part = 4; cursor = (first_cursor + 5) % 4; } else if (leftEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[0], boundOnScreen[1])) { part = 5; cursor = (first_cursor + 0) % 4; } else if (bottomEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[1], boundOnScreen[2])) { part = 6; cursor = (first_cursor + 2) % 4; } else if (rightEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[2], boundOnScreen[3])) { part = 7; cursor = (first_cursor + 4) % 4; } else if (topEdge && TUtil.isPointProjectionInLineSegment(screenPos, boundOnScreen[3], boundOnScreen[0])) { part = 8; cursor = (first_cursor + 6) % 4; } else if (TUtil.distanceBetweenPoints(screenPos, anchorPosOnScreen) <= ctrl_size) { part = 10; } else if (insideBound) { part = 0; } else if (currentTool != TDocument.TOOL_BOUNDING && currentTool != TDocument.TOOL_PUZZLE) { if (TUtil.distanceBetweenPoints(screenPos, boundOnScreen[0]) <= ctrl_size * 3 || TUtil.distanceBetweenPoints(screenPos, boundOnScreen[1]) <= ctrl_size * 3 || TUtil.distanceBetweenPoints(screenPos, boundOnScreen[2]) <= ctrl_size * 3 || TUtil.distanceBetweenPoints(screenPos, boundOnScreen[3]) <= ctrl_size * 3) { part = 9; } } return(part); }
private void drawSelectedBound(Graphics g) { PointF[] bound = null; TActor actor = this.selectedActor(); if (currentTool == TDocument.TOOL_BOUNDING) { if (actor != null) { bound = actor.interactionBoundOnScreen(); } } else if (currentTool == TDocument.TOOL_PUZZLE) { if (actor != null && actor.puzzle) { bound = actor.puzzleAreaOnScreen(); } } else { bound = this.selectedBound(); } if (bound != null) { Color boundColor; switch (currentTool) { case TDocument.TOOL_BOUNDING: boundColor = Color.Red; break; case TDocument.TOOL_PUZZLE: boundColor = Color.Blue; break; default: boundColor = Color.Black; break; } // draw rectangle Pen pen = new Pen(boundColor, 1); pen.DashStyle = DashStyle.Custom; pen.DashPattern = new float[] { 4, 4 }; g.DrawPolygon(pen, bound); // draw control point const int ctrl_size = 6; Pen ctrl_pen = new Pen(boundColor, 1); Brush ctrl_brush = new SolidBrush(Color.White); Rectangle ctrl_rect; for (int i = 0; i < bound.Length; i++) { // corner ctrl_rect = new Rectangle((int)(bound[i].X - ctrl_size / 2), (int)(bound[i].Y - ctrl_size / 2), ctrl_size, ctrl_size); g.FillRectangle(ctrl_brush, ctrl_rect); g.DrawRectangle(ctrl_pen, ctrl_rect); // edge int j = (i + 1) % bound.Length; ctrl_rect = new Rectangle((int)((bound[i].X + bound[j].X - ctrl_size) / 2), (int)((bound[i].Y + bound[j].Y - ctrl_size) / 2), ctrl_size, ctrl_size); g.FillRectangle(ctrl_brush, ctrl_rect); g.DrawRectangle(ctrl_pen, ctrl_rect); } // draw anchor point if (actor != null && (currentTool != TDocument.TOOL_BOUNDING && currentTool != TDocument.TOOL_PUZZLE)) { const int anchor_line_size = 10; const int anchor_circle_size = 6; RectangleF actorBound = actor.bound(); PointF anchorPosF = actor.logicalToScreen(new PointF(actor.anchor.X * actorBound.Width, actor.anchor.Y * actorBound.Height)); Point anchorPos = new Point((int)anchorPosF.X, (int)anchorPosF.Y); g.DrawLine(ctrl_pen, anchorPos.X - anchor_line_size / 2, anchorPos.Y, anchorPos.X - anchor_circle_size / 2, anchorPos.Y); g.DrawLine(ctrl_pen, anchorPos.X + anchor_line_size / 2, anchorPos.Y, anchorPos.X + anchor_circle_size / 2, anchorPos.Y); g.DrawLine(ctrl_pen, anchorPos.X, anchorPos.Y - anchor_line_size / 2, anchorPos.X, anchorPos.Y - anchor_circle_size / 2); g.DrawLine(ctrl_pen, anchorPos.X, anchorPos.Y + anchor_line_size / 2, anchorPos.X, anchorPos.Y + anchor_circle_size / 2); g.DrawEllipse(ctrl_pen, anchorPos.X - anchor_circle_size / 2, anchorPos.Y - anchor_circle_size / 2, anchor_circle_size, anchor_circle_size); g.FillRectangle(Brushes.Black, anchorPos.X, anchorPos.Y, 1, 1); } } }