我有一条基于我知道的两个(x,y)坐标的线.该行有一个起点和终点.现在我想在线的终点添加一个箭头.
我知道箭头是等边三角形,因此每个角度都有60度.另外,我知道一边的长度,即20.我也没有三角形的边缘(这是直线的终点).
如何计算三角形的其他两个点?我知道我应该使用一些三角函数但是如何?
Ps线的终点应该是箭头的尖端.
这是一个示例LINQPad程序,它显示了如何执行此操作:
void Main()
{
const int imageWidth = 512;
Bitmap b = new Bitmap(imageWidth , imageWidth , PixelFormat.Format24bppRgb);
Random r = new Random();
for (int index = 0; index < 10; index++)
{
Point fromPoint = new Point(0, 0);
Point toPoint = new Point(0, 0);
// Ensure we actually have a line
while (fromPoint == toPoint)
{
fromPoint = new Point(r.Next(imageWidth ), r.Next(imageWidth ));
toPoint = new Point(r.Next(imageWidth ), r.Next(imageWidth ));
}
// dx,dy = arrow line vector
var dx = toPoint.X - fromPoint.X;
var dy = toPoint.Y - fromPoint.Y;
// normalize
var length = Math.Sqrt(dx * dx + dy * dy);
var unitDx = dx / length;
var unitDy = dy / length;
// increase this to get a larger arrow head
const int arrowHeadBoxSize = 10;
var arrowPoint1 = new Point(
Convert.ToInt32(toPoint.X - unitDx * arrowHeadBoxSize - unitDy * arrowHeadBoxSize),
Convert.ToInt32(toPoint.Y - unitDy * arrowHeadBoxSize + unitDx * arrowHeadBoxSize));
var arrowPoint2 = new Point(
Convert.ToInt32(toPoint.X - unitDx * arrowHeadBoxSize + unitDy * arrowHeadBoxSize),
Convert.ToInt32(toPoint.Y - unitDy * arrowHeadBoxSize - unitDx * arrowHeadBoxSize));
using (Graphics g = Graphics.FromImage(b))
{
if (index == 0)
g.Clear(Color.White);
g.DrawLine(Pens.Black, fromPoint, toPoint);
g.DrawLine(Pens.Black, toPoint, arrowPoint1);
g.DrawLine(Pens.Black, toPoint, arrowPoint2);
}
}
using (var stream = new MemoryStream())
{
b.Save(stream, ImageFormat.Png);
Util.Image(stream.ToArray()).Dump();
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,你:
请注意,如果您希望箭头线的角度不同于45度,则必须使用其他方法.
上面的程序每次都会绘制10个随机箭头,这是一个例子:

你不需要触发器,只需要一些矢量算术......
假设线从A到B,箭头的前顶点在B处.箭头的长度是h = 10(√3),它的半宽是w = 10.我们将表示单位矢量来自A至B为U =(B-A)/ | B-A | (即,差值除以差值的长度),与此垂直的单位矢量为V = [-U y,U x ].
从这些量,您可以计算箭头的两个后顶点B - hU±wV.
在C++中:
struct vec { float x, y; /* … */ };
void arrowhead(vec A, vec B, vec& v1, vec& v2) {
float h = 10*sqrtf(3), w = 10;
vec U = (B - A)/(B - A).length();
vec V = vec(-U.y, U.x);
v1 = B - h*U + w*V;
v2 = B - h*U - w*V;
}
Run Code Online (Sandbox Code Playgroud)
如果要指定不同的角度,则需要一些触发.计算的不同的值h和w.假设你想要一个长度为h和尖角θ的箭头,那么w = h tan(θ/ 2).然而在实践中,这是最简单的指定h和w直接.