3
A
回答
2
需要一些小小的幾何圖形才能找出形成箭頭的三角形的拐角。
假設線條從P0到P1,並且我們希望P1的箭頭尖端。爲了找到箭頭的「后角」,我們希望沿着線從尖端向後移動,然後左右轉動以使箭頭有一定的寬度。
如果線條與x或y軸對齊,這將很簡單。爲了以任何角度處理線條,我們可以構建一個座標系,其座標軸與原始線平行並垂直。我們將這些軸稱爲u和v,u指向線的方向,v垂直於它。
現在我們可以從P0開始,通過加入由u和v確定的方向移動到角上,按照我們想要的任何箭頭長度和寬度進行縮放。
在代碼:
constexpr int Round(float x) { return static_cast<int>(x + 0.5f); }
// Draws a line from p0 to p1 with an arrowhead at p1. Arrowhead is outlined
// with the current pen and filled with the current brush.
void DrawArrow(HDC hdc, POINT p0, POINT p1, int head_length, int head_width) {
::MoveToEx(hdc, p0.x, p0.y, nullptr);
::LineTo(hdc, p1.x, p1.y);
const float dx = static_cast<float>(p1.x - p0.x);
const float dy = static_cast<float>(p1.y - p0.y);
const auto length = std::sqrt(dx*dx + dy*dy);
if (head_length < 1 || length < head_length) return;
// ux,uy is a unit vector parallel to the line.
const auto ux = dx/length;
const auto uy = dy/length;
// vx,vy is a unit vector perpendicular to ux,uy
const auto vx = -uy;
const auto vy = ux;
const auto half_width = 0.5f * head_width;
const POINT arrow[3] =
{ p1,
POINT{ Round(p1.x - head_length*ux + half_width*vx),
Round(p1.y - head_length*uy + half_width*vy) },
POINT{ Round(p1.x - head_length*ux - half_width*vx),
Round(p1.y - head_length*uy - half_width*vy) }
};
::Polygon(hdc, arrow, 3);
}
和(使用WTL)演示:
LRESULT OnPaint(UINT, WPARAM, LPARAM, BOOL &) {
PAINTSTRUCT ps;
BeginPaint(&ps);
RECT rc;
GetClientRect(&rc);
const auto origin = POINT{rc.left + (rc.right - rc.left)/2,
rc.top + (rc.bottom - rc.top)/2 };
const auto pi = 3.1415926f;
const auto tau = 2.0f*pi;
const auto cxInch = ::GetDeviceCaps(ps.hdc, LOGPIXELSX);
const auto radius = 2.0f * cxInch;
const auto size = Round(0.333f * cxInch);
for (float theta = 0.0f; theta < tau; theta += tau/12.0f) {
const auto p1 =
POINT{Round(origin.x + radius * std::cos(theta)),
Round(origin.y + radius * std::sin(theta))};
DrawArrow(ps.hdc, origin, p1, size, size/3);
}
EndPaint(&ps);
return 0;
}
相關問題
- 1. 用Java中的箭頭繪製線條
- 2. 在Javascript中繪製一條帶箭頭的直線
- 3. 在opengl中繪製一個箭頭ES
- 4. 在Pygame中繪製一個箭頭
- 5. 在C中的一個Picturebox上繪製一個箭頭#
- 6. Android - 如何正確繪製一個帶箭頭的箭頭?
- 7. 在VB6中的線對象上繪製一個箭頭
- 8. 用箭頭填充帶有箭頭的svg路徑作爲頭
- 9. 在PolylineConnection的末尾創建一個空心箭頭?
- 10. 在畫布上的彎頭連接器末端繪製箭頭
- 11. 繪製曲線SVG箭頭線的div
- 12. 在android中繪製箭頭頭
- 13. 在gnuplot的一條曲線前面和另一條曲線的前面繪製一個箭頭
- 14. 在線算法繪製箭頭
- 15. 在第一行文本末尾切換箭頭
- 16. Jfreechart:在甘特圖中繪製線條箭頭
- 17. 在兩點之間繪製一條帶NSBezierPath的箭頭
- 18. 如何在頁面末尾繪製一條線?
- 19. 如何:用箭頭畫一條線?
- 20. 如何用箭頭畫一條線?
- 21. 繪製符合PyGame中線條方向的箭頭
- 22. 用matplotlib中的箭頭繪製線條圖
- 23. 沿着三條線或兩條向量繪製箭頭助手
- 24. 如何使用箭頭鍵繪製線條(線段)?
- 25. 用CGContext繪製三角形/箭頭線
- 26. 使用Javascript線繪製箭頭至
- 27. JavaFX線/箭頭箭頭
- 28. 如何在JFrame中的兩個標籤之間繪製箭頭/線條?
- 29. 如何在SVG/raphael的貝塞爾曲線的末端繪製箭頭?
- 30. 動態繪製箭頭android
的Windows GDI?認爲你應該標記窗口來獲得幫助 – Elemental 2010-11-12 15:00:52
你有沒有嘗試Pen :: SetEndCap()? – 2010-11-12 15:33:19