用C#计算一个数值计算方法A,不知道能不能算得出来!

I'm going quite mad tring to calculate the point along the given line A-B, at a given distance from A, so that I can "draw" the line between two given points. It sounded simple enough at the outset, but I can't seem to get it right. Worse still, I don't understand where I've gone wrong. Geometry (and math in general) is NOT my strong suite.
I have read similar questions and there answers on SO. In fact I lifted my current implementation of CalculatePoint function directly from Mads Elvheim's answer to:
(plus a correction in a later comment - if I understand him correctly) because my indepedent attempts to solve the problem were getting me nowhere, except a first class express ticket frusterpationland.
Here's my UPDATED code (please see the EDIT notes a bottom of post):
using System.D
using System.Windows.F
namespace DrawLines
public class MainForm : Form
// =====================================================================
// Here's the part I'm having trouble with. I don't really understand
// how this is suposed to work, so I can't seem to get it right!
// ---------------------------------------------------------------------
// A "local indirector" - Just so I don't have go down and edit the
// actual call everytime this bluddy thing changes names.
private Point CalculatePoint(Point a, Point b, int distance) {
return CalculatePoint_ByAgentFire(a, b, distance);
#region CalculatePoint_ByAgentFire
//AgentFire: Better approach (you can rename the struct if you need):
struct Vector2
public readonly double X;
public readonly double Y;
public Vector2(double x, double y) {
public static Vector2 operator -(Vector2 a, Vector2 b) {
return new Vector2(b.X - a.X, b.Y - a.Y);
public static Vector2 operator *(Vector2 a, double d) {
return new Vector2(a.X * d, a.Y * d);
public override string ToString() {
return string.Format("[{0}, {1}]", X, Y);
// For getting the midpoint you just need to do the (a - b) * d action:
//static void Main(string[] args)
Vector2 a = new Vector2(1, 1);
Vector2 b = new Vector2(3, 1);
float distance = 0.5f; // From 0.0 to 1.0.
Vector2 c = (a - b) *
Console.WriteLine(c);
private Point CalculatePoint_ByAgentFire(Point a, Point b, int distance) {
var vA = new Vector2(a.X, a.Y);
var vB = new Vector2(b.X, b.Y);
double lengthOfHypotenuse = LengthOfHypotenuseAsDouble(a,b);
double portionOfDistanceFromAtoB = distance / lengthOfH
var vC = (vA - vB) * portionOfDistanceFromAtoB;
Console.WriteLine("vC="+vC);
return new Point((int)(vC.X+0.5), (int)(vC.Y+0.5));
// Returns the length of the hypotenuse rounded to an integer, using
// Pythagoras' Theorem for right angle triangles: The length of the
// hypotenuse equals the sum of the square of the other two sides.
// Ergo: h = Sqrt(a*a + b*b)
private double LengthOfHypotenuseAsDouble(Point a, Point b) {
double aSq = Math.Pow(Math.Abs(a.X - b.X), 2); // horizontal length squared
double bSq = Math.Pow(Math.Abs(b.Y - b.Y), 2); // vertical length
return Math.Sqrt(aSq + bSq); // length of the hypotenuse
#endregion
//dbaseman: I thought something looked strange about the formula ... the question
//you linked was how to get the point at a distance after B, whereas you want the
//distance after A. This should give you the right answer, the start point plus
//distance in the vector direction.
// Didn't work as per: /albums/jj496/corlettk/?action=view&current=DrawLinesAB-broken_zps.jpg
private Point CalculatePoint_ByDbaseman(Point a, Point b, int distance) {
// a. calculate the vector from a to b:
double vectorX = b.X - a.X;
double vectorY = b.Y - a.Y;
// b. calculate the length:
double magnitude = Math.Sqrt(vectorX * vectorX + vectorY * vectorY);
// c. normalize the vector to unit length:
vectorX /=
vectorY /=
// d. calculate and Draw the new vector, which is x1y1 + vxvy * (mag + distance).
return new Point(
(int)((double)a.X + vectorX * distance)
// x = col
, (int)((double)a.Y + vectorY * distance)
// y = row
// MBo: Try to remove 'magnitude' term in the parentheses both for X and for Y expressions.
// Didn't work as per: /albums/jj496/corlettk/?action=view&current=DrawLinesAB-broken_zps.jpg
//private Point CalculatePoint_ByMBo(Point a, Point b, int distance) {
// a. calculate the vector from a to b:
double vectorX = b.X - a.X;
double vectorY = b.Y - a.Y;
// b. calculate the length:
double magnitude = Math.Sqrt(vectorX * vectorX + vectorY * vectorY);
// c. normalize the vector to unit length:
vectorX /=
vectorY /=
// d. calculate and Draw the new vector, which is x1y1 + vxvy * (mag + distance).
return new Point(
((double)a.X + vectorX * distance)
((double)a.X + vectorX * distance)
// Didn't work
//private Point CalculatePoint_ByUser1556110(Point a, Point b, int distance) {
Double magnitude = Math.Sqrt(Math.Pow(b.Y - a.Y, 2) + Math.Pow(b.X - a.X, 2));
return new Point(
(int)(a.X + distance * (b.X - a.X) / magnitude + 0.5)
, (int)(a.Y + distance * (b.Y - a.Y) / magnitude + 0.5)
// didn't work
//private static Point CalculatePoint_ByCadairIdris(Point a, Point b, int distance) {
// a. calculate the vector from a to b:
double vectorX = b.X - a.X;
double vectorY = b.Y - a.Y;
// b. calculate the proportion of hypotenuse
double factor = distance / Math.Sqrt(vectorX*vectorX + vectorY*vectorY);
// c. factor the lengths
vectorX *=
vectorY *=
// d. calculate and Draw the new vector,
return new Point((int)(a.X + vectorX), (int)(a.Y + vectorY));
// Returns a point along the line A-B at the given distance from A
// based on Mads Elvheim's answer to:
// /questions/1800138/given-a-start-and-end-point-and-a-distance-calculate-a-point-along-a-line
private Point MyCalculatePoint(Point a, Point b, int distance) {
// a. calculate the vector from o to g:
double vectorX = b.X - a.X;
double vectorY = b.Y - a.Y;
// b. calculate the length:
double magnitude = Math.Sqrt(vectorX * vectorX + vectorY * vectorY);
// c. normalize the vector to unit length:
vectorX /=
vectorY /=
// d. calculate and Draw the new vector, which is x1y1 + vxvy * (mag + distance).
return new Point(
(int)(((double)a.X + vectorX * (magnitude + distance)) + 0.5) // x = col
, (int)(((double)a.Y + vectorY * (magnitude + distance)) + 0.5) // y = row
// =====================================================================
private const int CELL_SIZE = 4; // width and height of each "cell" in the bitmap.
private readonly Bitmap _ // to draw on (displayed in picBox1).
private readonly Graphics _ // to draw with.
// actual points on _theLineString are painted red.
private static readonly SolidBrush _thePointBrush = new SolidBrush(Color.Red);
// ... and are labeled in Red, Courier New, 12 point, Bold
private static readonly SolidBrush _theLabelBrush = new SolidBrush(Color.Red);
private static readonly Font _theLabelFont = new Font("Courier New", 12, FontStyle.Bold);
// the interveening calculated cells on the lines between actaul points are painted Black.
private static readonly SolidBrush _theLineBrush = new SolidBrush(Color.Black);
// the points in my line-string.
private static readonly Point[] _theLineString = new Point[] {
new Point(170,
new Point( 85,
//new Point(209,
//new Point( 98, 120), // D
//new Point(158,
//new Point(
//new Point( 42, 177), // G
//new Point(191, 146), // H
//new Point( 25, 128), // I
//new Point( 95,
public MainForm() {
InitializeComponent();
// initialise "the graphics system".
_bitmap = new Bitmap(picBox1.Width, picBox1.Height);
_graphics = Graphics.FromImage(_bitmap);
picBox1.Image = _
#region actual drawing on the Grpahics
private void DrawCell(int x, int y, Brush brush) {
_graphics.FillRectangle(
, x * CELL_SIZE, y * CELL_SIZE
, CELL_SIZE, CELL_SIZE
// width, heigth
private void DrawLabel(int x, int y, char c) {
string s = c.ToString();
_graphics.DrawString(
s, _theLabelFont, _theLabelBrush
, x * CELL_SIZE + 5
, y * CELL_SIZE - 8
// ... there should be no mention of _graphics or CELL_SIZE below here ...
#endregion
#region draw points on form load
private void MainForm_Load(object sender, EventArgs e) {
DrawPoints();
// draws and labels each point in _theLineString
private void DrawPoints() {
char c = 'A'; // label text, as a char so we can increment it for each point.
foreach ( Point p in _theLineString ) {
DrawCell(p.X, p.Y, _thePointBrush);
DrawLabel(p.X, p.Y, c++);
#endregion
#region DrawLines on button click
private void btnDrawLines_Click(object sender, EventArgs e) {
DrawLinesBetweenPointsInTheString();
// Draws "the lines" between the points in _theLineString.
private void DrawLinesBetweenPointsInTheString() {
int n = _theLineString.Length - 1; // one less line-segment than points
for ( int i = 0; i & ++i )
Draw(_theLineString[i], _theLineString[i + 1]);
picBox1.Invalidate(); // tell the graphics system that the picture box needs to be repainted.
// Draws all the cells along the line from Point "a" to Point "b".
private void Draw(Point a, Point b) {
int maxDistance = LengthOfHypotenuse(a, b);
for ( int distance = 1; distance & maxD ++distance ) {
var point = CalculatePoint(a, b, distance);
DrawCell(point.X, point.X, _theLineBrush);
// Returns the length of the hypotenuse rounded to an integer, using
// Pythagoras' Theorem for right angle triangles: The length of the
// hypotenuse equals the sum of the square of the other two sides.
// Ergo: h = Sqrt(a*a + b*b)
private int LengthOfHypotenuse(Point a, Point b) {
double aSq = Math.Pow(Math.Abs(a.X - b.X), 2); // horizontal length squared
double bSq = Math.Pow(Math.Abs(b.Y - b.Y), 2); // vertical length
return (int)(Math.Sqrt(aSq + bSq) + 0.5); // length of the hypotenuse
#endregion
#region Windows Form Designer generated code
/// &summary&
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// &/summary&
private void InitializeComponent() {
this.picBox1 = new System.Windows.Forms.PictureBox();
this.btnDrawLines = new System.Windows.Forms.Button();
((ponentModel.ISupportInitialize)(this.picBox1)).BeginInit();
this.SuspendLayout();
// picBox1
this.picBox1.Dock = System.Windows.Forms.DockStyle.F
this.picBox1.Location = new System.Drawing.Point(0, 0);
this.picBox1.Name = "picBox1";
this.picBox1.Size = new System.Drawing.Size();
this.picBox1.TabIndex = 0;
this.picBox1.TabStop =
// btnDrawLines
this.btnDrawLines.Location = new System.Drawing.Point(23, 24);
this.btnDrawLines.Name = "btnDrawLines";
this.btnDrawLines.Size = new System.Drawing.Size(77, 23);
this.btnDrawLines.TabIndex = 1;
this.btnDrawLines.Text = "Draw Lines";
this.btnDrawLines.UseVisualStyleBackColor =
this.btnDrawLines.Click += new System.EventHandler(this.btnDrawLines_Click);
// MainForm
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.F
this.ClientSize = new System.Drawing.Size();
this.Controls.Add(this.btnDrawLines);
this.Controls.Add(this.picBox1);
this.Location = new System.Drawing.Point(10, 10);
this.MinimumSize = new System.Drawing.Size();
this.Name = "MainForm";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.H
this.StartPosition = System.Windows.Forms.FormStartPosition.M
this.Text = "Draw Lines on a Matrix.";
this.Load += new System.EventHandler(this.MainForm_Load);
((ponentModel.ISupportInitialize)(this.picBox1)).EndInit();
this.ResumeLayout(false);
private System.Windows.Forms.PictureBox picBox1;
private System.Windows.Forms.Button btnDrawL
#endregion
Sorry if it's a bit long, but this an is
exhumed from my real project, which is an implementation of the
to run the ... i.e. a maze runner.
What I actually want to do is pre-calculate a "fence" (i.e. a buffered ) around two given points (origin and goal) in the maze (a matrix), such that all points within the "fence" are within a given distance from "the straight line between the two points", in order to quickly eliminate the hundreds-of-thousands of possible paths which are heading away from the goal.
Note that this programming challenge closed years ago, so there's no issue with "competitive plagerism" here. No this is not homework, in fact I'm a professional programmer... I'm just WAAAAY out of my comfort zone here, even with relatively simple geometry. Sigh.
So... Please can anyone give me any pointers to help me get the CalculatePoint function to correctly: Calculate a point along the line A-B at the given distance from A?
Thanks in advance for your generosity... even in reading this far.
Cheers. Keith.
EDIT: I just updated the posted source code becuase:
(1) I just realised that it wasn't self contained. I forgot about the seperate MainForm.Designer.cs file, which I've appended to the bottom of the posted code.
(2) The latest version includes what I've tried so far, with a photobucket link to a picture of what each failure looks like... and they're all the same. Huy? WTF?
I suppose my problem may be elsewhere, like some funky windows form setting that was previously missed by everyone else because I forgot to post the designer-generated code... Except everythingelse (in my actual project) paints exactly where I expect it to, so why should a calculated point be any different. I don't know!?!?!? I'm pretty frustrated and I'm getting cranky, so I think I'll leave t-)
Goes to show how much we routinely underestimate how much effort it'll take to make a computer do ANYthing... even just draw a simple line... it's not even a curve, let alone a great circle or a transverse mercator or anything fancy... just a simple bluddy line!?!?!? ;-)
A BIG Thank You to everyone who posted!
Cheers again. Keith.
解决方案 Calculate the vector AB
First define the vector from point A(1,-1) to point B(2,4) substracting A from B.
The vector would be Vab(1,5).
Calculate the length of AB
Use Pythagorean theorem to calculate the length of vector AB.
|Vab| = SQRT(1?+5?)
The Length is (rounded) 5.1
Calculate the unit vector
Divide the vector by its length to get the unit vector (the vector with length 1).
V1(1/5.1,5/5.1) = V1(0.2, 0.98)
Calculate the vector with length 4
Now multiply V1 with the length you want, for example 4, to get Vt.
Vt(0.2*4,0.98*4) = Vt(0.8,3.92)
Calculate target point
Add the vector Vt to point A to get point T (target).
T = A + Vt = T(1.8,2.92)
EDIT: Answer to your edit
The method LengthOfHypotenuse should look like that
fixed an error on calculating bSq
and removed redundant Math.Abs call, because a pow of 2 is always positive
removed the addition of 0.5, don't know why you would need that
you should at least use a float as return value (double or decimal would work also)
//You should work with Vector2 class instead of Point and use their Length property
private double LengthOfHypotenuse(Point a, Point b) {
double aSq = Math.Pow(a.X - b.X, 2); // horizontal length squared
double bSq = Math.Pow(a.Y - b.Y, 2); // vertical length
return Math.Sqrt(aSq + bSq); // length of the hypotenuse
The method Draw(Point a, Point b) should look like that:
Corrected DrawCell() call
private void Draw(Point a, Point b) {
double maxDistance = LengthOfHypotenuse(a, b);
for (int distance = 0; distance & maxD ++distance) {
var point = CalculatePoint(new Vector2(a), new Vector2(b), distance);
DrawCell(point.X, point.Y, _theLineBrush);
Your CalculatePoint(Point a, Point b, int distance) method:
Moved some calculations into Vector2 class
private Point CalculatePoint(Vector2 a, Vector2 b, int distance) {
Vector2 vectorAB = a -
return a + vectorAB.UnitVector *
I have extended the Vector class for you to add the missing operators (credits to AgentFire)
//AgentFire: Better approach (you can rename the struct if you need):
struct Vector2 {
public readonly double X;
public readonly double Y;
public Vector2(Point p) : this(p.X,p.Y) {
public Vector2(double x, double y) {
public static Vector2 operator -(Vector2 a, Vector2 b) {
return new Vector2(b.X - a.X, b.Y - a.Y);
public static Vector2 operator +(Vector2 a, Vector2 b) {
return new Vector2(b.X + a.X, b.Y + a.Y);
public static Vector2 operator *(Vector2 a, double d) {
return new Vector2(a.X * d, a.Y * d);
public static Vector2 operator /(Vector2 a, double d) {
return new Vector2(a.X / d, a.Y / d);
public static implicit operator Point(Vector2 a) {
return new Point((int)a.X, (int)a.Y);
public Vector2 UnitVector {
get { return this / L }
public double Length {
double aSq = Math.Pow(X, 2);
double bSq = Math.Pow(Y, 2);
return Math.Sqrt(aSq + bSq);
public override string ToString() {
return string.Format("[{0}, {1}]", X, Y);
本文地址: &
我要疯了相当特林计算点沿给定线A-B,在从A一定距离,这样我可以在两个特定点之间“画”就行了。这听起来在一开始很简单,但我似乎无法得到它的权利。更糟糕的是,我不明白的地方我已经错了。几何(和一般的数学)不是我的套件。我看过类似的问题,并因此有回答了。其实我抬起当前实现CalculatePoint功能的直接的的Mads Elvheim 的的回答:Given起点和终点,和距离,计算沿线点(加上后来评论的修正 - 如果我没有理解错了他),因为我上独立试图解决的问题是让我无处,除第一类ex preSS票frusterpationland。下面是我的更新时间: code(请参阅编辑笔记后的底部): 使用系统;使用System.Drawing中;使用System.Windows.Forms的;命名空间DrawLines{
公共类的MainForm:表格
// ================================================ =====================
//这是我遇到的麻烦的部分。我真的不明白
//这是如何suposed工作,所以我似乎无法得到它的权利!
// ------------------------------------------------ ---------------------
// A“本地indirector” - 只是让我没有下去,并编辑
//实际调用每次这种事情bluddy改变名称。
私人点CalculatePoint(A点,B点,INT距离){
返回CalculatePoint_ByAgentFire(A,B,距离);
#区域CalculatePoint_ByAgentFire
// AgentFire:更好的方法(你可以,如果你需要重命名结构):
结构Vector2
公共只读双X;
公共只读双Y;
公共Vector2(双X,双Y){
this.X = X;
this.Y = Y;
公共静态Vector2运营商 - (Vector2一,Vector2 B){
返回新Vector2(b.X
公共静态Vector2符*(Vector2一,双D){
返回新Vector2(a.X * D,a.Y * D);
公共重写字符串的ToString(){
返回的String.Format(“[{0},{1}]”,X,Y);
//为了得到中点你只需要做(A
B)* D行动:
//静态无效的主要(字串[] args)
// Vector2一个=新Vector2(1,1);
// Vector2 B =新Vector2(3,1);
//浮动距离= 0.5F; //从0.0到1.0。
// Vector2 C =(A
B)*的距离;
// Console.WriteLine(C);
私人点CalculatePoint_ByAgentFire(A点,B点,INT距离){
VAR VA =新Vector2(a.X,a.Y);
变种VB =新Vector2(b.X,b.Y);
双lengthOfHypotenuse = LengthOfHypotenuseAsDouble(A,B);
双portionOfDistanceFromAtoB =距离/ lengthOfH
VAR VC =(VA
Others)* portionOfDistanceFromAtoB;
Console.WriteLine(“VC =”+ VC);
返回新点((int)的(vC.X + 0.5),(INT)(vC.Y + 0.5));
//返回斜边长度舍入为整数,使用
//毕达哥拉斯定理直角三角:的长度
//斜边等于其他两个边的平方的总和。
//人机工程学:H = SQRT(A * A + B * B)
私人双LengthOfHypotenuseAsDouble(A点,B点){
双ASQ = Math.Pow(Math.Abs(a.X
b.X),2); //水平长度的平方
双BSQ = Math.Pow(Math.Abs(b.Y
b.Y),2); //垂直长度的平方
返回的Math.sqrt(ASQ + BSQ); //斜边长度
#endregion
// dbaseman:我觉得好像有奇怪的公式...的问题
//你挂的是如何在后B的距离明白了吧,而你想要的
// A.距离后,这应该给你正确的答案,起点加
//在矢量方向上的距离。
//没有工作按: /albums/jj496/corlettk/?action=view&current=DrawLinesAB-broken_zps.jpg
私人点CalculatePoint_ByDbaseman(A点,B点,INT距离){
// 一个。从计算向量至b:
双vectorX = b.X
双vectorY = b.Y
// B。计算长度:
双级=的Math.sqrt(vectorX * vectorX + vectorY * vectorY);
// C。规范化向量单位长度:
vectorX / =幅度;
vectorY / =幅度;
//?。计算和绘制新的载体,它是X1Y1 + vxvy *(MAG +距离)。
返回新的点(
(INT)((双)a.X + vectorX *距离)// X =山坳
(INT)((双)a.Y + vectorY *距离)// Y =行
// MBO:尝试在括号既为X和Y的前pressions删除“幅度”一词。
//没有工作按: /albums/jj496/corlettk/?action=view&current=DrawLinesAB-broken_zps.jpg
//私有点CalculatePoint_ByMBo(A点,B点,INT距离){
// 一个。从计算向量至b:
//双vectorX = b.X
//双vectorY = b.Y
// // B。计算长度:
//双幅度=的Math.sqrt(vectorX * vectorX + vectorY * vectorY);
// C。规范化向量单位长度:
// vectorX / =幅度;
// vectorY / =幅度;
// //?。计算和绘制新的载体,它是X1Y1 + vxvy *(MAG +距离)。
//返回新的点(
//(INT)(((双)a.X + vectorX *距离)+ 0.5)
//(INT)(((双)a.X + vectorX *距离)+ 0.5)
//没有工作
//私有点CalculatePoint_ByUser1556110(A点,B点,INT距离){
//双幅度=的Math.sqrt(Math.Pow(b.Y
a.Y,2)+ Math.Pow(b.X
a.X,2));
//返回新的点(
//(INT)(a.X +距离*(b.X
a.X)/幅度+ 0.5)
//(INT)(a.Y +距离*(b.Y
a.Y)/幅度+ 0.5)
//没有工作
//私有静态点CalculatePoint_ByCadairIdris(A点,B点,INT距离){
// 一个。从计算向量至b:
//双vectorX = b.X
//双vectorY = b.Y
// // B。计算斜边的比例
//双系数=距离/的Math.sqrt(vectorX * vectorX + vectorY * vectorY);
// C。因素的长度
// vectorX * =因素;
// vectorY * =因素;
// //?。计算和绘制新的向量,
//返回新的点((INT)(a.X + vectorX),(INT)(a.Y + vectorY));
//在从A给定距离返回沿线A-B点
//基础上的Mads Elvheim的回答:
// /questions/1800138/given-a-start-and-end-point-and-a-distance-calculate-a-point-along-a-line
私人点MyCalculatePoint(A点,B点,INT距离){
// 一个。由O至g计算矢量:
双vectorX = b.X
双vectorY = b.Y
// B。计算长度:
双级=的Math.sqrt(vectorX * vectorX + vectorY * vectorY);
// C。规范化向量单位长度:
vectorX / =幅度;
vectorY / =幅度;
//?。计算和绘制新的载体,它是X1Y1 + vxvy *(MAG +距离)。
返回新的点(
(INT)(((双)a.X + vectorX *(大小+距离))+ 0.5)// X =山坳
(INT)(((双)a.Y + vectorY *(大小+距离))+ 0.5)// Y =行
// ================================================ =====================
私人const int的CELL_SIZE = 4; //宽度和位图中的每个“单元”的高度。
私人只读位图_ //借鉴(在picBox1显示)。
私人只读图形_ //打水。
在_theLineString //实际点涂成红色。
私人静态只读SolidBrush _thePointBrush =新SolidBrush(Color.Red);
// ...,并贴有红色,宋体,12点,粗体
私人静态只读SolidBrush _theLabelBrush =新SolidBrush(Color.Red);
私人静态只读字体_theLabelFont =新的字体(“宋体”,12,FontStyle.Bold);
//对actaul点之间的线路interveening计算单元被漆成黑色。
私人静态只读SolidBrush _theLineBrush =新SolidBrush(Color.Black);
//我的线串点。
私人静态只读点[] = _theLineString新的Point [] {
新点(170,85),//一个
新的点(85,70),// B
//新的Point(209,66)// C
//新的点(98,120),//?
//新的Point(158,19)//?
//新点(2,61)//?F
//新的点(42,177),//摹
//新点(191,146),// H
//新的点(25,128),//我
//新的点(95,24)∥焦
公众的MainForm(){
的InitializeComponent();
//初始化“图形系统”。
_bitmap =新位图(picBox1.Width,picBox1.Height);
_graphics = Graphics.FromImage(_bitmap);
picBox1.Image = _
在Grpahics#区域实际绘图
私人无效DrawCell(INT X,INT Y,刷刷){
_graphics.FillRectangle(
,X * CELL_SIZE,Y * CELL_SIZE // X,Y
,CELL_SIZE,CELL_SIZE //宽,heigth
私人无效DrawLabel(INT X,INT Y,焦三){
字符串s = c.ToString();
_graphics.DrawString(
S,_theLabelFont,_theLabelBrush
,X * CELL_SIZE + 5 //点?x
,Y * CELL_SIZE
// ...应该有_graphics没有提及或CELL_SIZE以下这里...
#endregion
#REGION借鉴的形式加载点
私人无效MainForm_Load(对象发件人,EventArgs的发送){
DrawPoints();
//绘制和标签_theLineString每个点
私人无效DrawPoints(){
焦C ='A'; //标签文本,作为一个char,所以我们可以增加它的每一个点。
的foreach(在_theLineString点p){
DrawCell(p.X,p.Y,_thePointBrush);
DrawLabel(p.X,p.Y,C ++);
#endregion
上按一下按钮#区域DrawLines
私人无效btnDrawLines_Click(对象发件人,EventArgs的发送){
DrawLinesBetweenPointsInTheString();
//绘制在_theLineString点之间的“线”。
私人无效DrawLinesBetweenPointsInTheString(){
INT N = _theLineString.Length
1; //少了一个线段比点
的for(int i = 0; I< N ++ I)
绘制(_theLineString [I],_theLineString第[i + 1]);
picBox1.Invalidate(); //告诉需要的图片框重新绘制图形系统。
//绘制所有细胞沿着点线“a”到“B”点。
私人无效抽奖(A点,B点){
INT maxDistance = LengthOfHypotenuse(A,B);
对于(INT距离= 1;距离< maxDistance ++距离){
VAR点= CalculatePoint(A,B,距离);
DrawCell(point.X,point.X,_theLineBrush);
//返回斜边长度舍入为整数,使用
//毕达哥拉斯定理直角三角:的长度
//斜边等于其他两个边的平方的总和。
//人机工程学:H = SQRT(A * A + B * B)
私人诠释LengthOfHypotenuse(A点,B点){
双ASQ = Math.Pow(Math.Abs(a.X
b.X),2); //水平长度的平方
双BSQ = Math.Pow(Math.Abs(b.Y
b.Y),2); //垂直长度的平方
回报(INT)(的Math.sqrt(ASQ + BSQ)+ 0.5); //斜边长度
#endregion
#region Windows窗体设计器生成的code
///<总结&
///设计器支持所需的方法 - 不要修改
///此方法的code编辑器的内容。
///< /总结&
私人无效的InitializeComponent(){
this.picBox1 =新System.Windows.Forms.PictureBox();
this.btnDrawLines =新System.Windows.Forms.Button();
((ponentModel.ISupportInitialize)(this.picBox1))BeginInit在()。
this.SuspendLayout();
// picBox1
this.picBox1.Dock = System.Windows.Forms.DockStyle.F
this.picBox1.Location =新System.Drawing.Point(0,0);
this.picBox1.Name =“picBox1”;
this.picBox1.Size =新System.Drawing.Size();
this.picBox1.TabIndex = 0;
this.picBox1.TabStop = FALSE;
// btnDrawLines
this.btnDrawLines.Location =新System.Drawing.Point(23,24);
this.btnDrawLines.Name =“btnDrawLines”;
this.btnDrawLines.Size =新System.Drawing.Size(77,23);
this.btnDrawLines.TabIndex = 1;
this.btnDrawLines.Text =“画线”;
this.btnDrawLines.UseVisualStyleBackColor = TRUE;
this.btnDrawLines.Click + =新System.EventHandler(this.btnDrawLines_Click);
//的MainForm
this.AutoScaleDimensions =新System.Drawing.SizeF(6F,13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.F
this.ClientSize =新System.Drawing.Size();
this.Controls.Add(this.btnDrawLines);
this.Controls.Add(this.picBox1);
this.Location =新System.Drawing.Point(10,10);
this.MinimumSize =新System.Drawing.Size();
this.Name =“MainForm的”;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.H
this.StartPosition = System.Windows.Forms.FormStartPosition.M
this.Text =“关于矩阵画线。”
this.Load + =新System.EventHandler(this.MainForm_Load);
((ponentModel.ISupportInitialize)(this.picBox1))EndInit在()。
this.ResumeLayout(假);
私人System.Windows.Forms.PictureBox picBox1;
私人System.Windows.Forms.Button btnDrawL
#endregion
}} 如果它是一个有点长,但这是一个
SSCCE 从我真正的项目,这是一个实现掘出 A *最短路径算法运行的 ...即一个迷宫亚军。我真正想要做的是pre-计算“篱笆”(即一个缓冲)围绕在迷宫两个特定点(原点和目标)(基质),以使得“围栏”之内的所有点是从“两点之间的直线”,一个给定的距离之内,以快速消除上百个的,成千上万的可能的路径这是从球门标题了。请注意,这个编程挑战年前关闭,所以有一个与“竞争性plagerism”在这里没有问题。不,这不是功课,其实我是一个专业的程序员......我只是WAAAAY在这里我的安乐窝,即使是相对简单的几何形状。叹了口气。所以......请任何人都可以给我任何指针帮我把CalculatePoint功能的正确:在从A给定距离计算沿线AB点 在此先感谢您的慷慨...即使在遥远阅读本。干杯。基思。 编辑:我刚刚更新了发布源$ C $ C监守:(1)我才意识到这不是自给。我忘了单独的MainForm 设计师 cs文件,我已经追加到贴code的底部。(2)的最新版本包含了我到目前为止已经试过,用的photobucket链接什么的每一次的失败看起来像一个画面......他们都是一样的。伊? WTF?我想我的问题可能是在其他地方一样,那是$ P $由其他人pviously错过了,因为我忘了张贴设计器生成的code一些时髦的Windows窗体设置......除了everythingelse(在我的实际项目)描绘正是我期望它,所以为什么要计算点有什么不同。我不知道!?!?!?我是pretty沮丧,我越来越胡思乱想,所以我想我会离开这个另一天;
- )正好说明我们有多么经常低估要花多少力气才能使一台计算机做什么......哪怕只是画一个简单的线......它甚至不是一条曲线,更何况是一个大圆或横向墨卡托或任何幻想......只是一个简单的bluddy线!?!?!? ;
- )非常感谢大家谁张贴!再次干杯。基思。解决方案
计算矢量AB
首先定义从A点矢量(1,-1),从B.点B(2,4)减去一个矢量是VAB(1,5)。 计算AB的长度 使用勾股定理计算矢量AB的长度。
| VAB | = SQRT(1?+5?) 总长(四舍五入)5.1
计算单位矢量 通过其长度除以向量获得的单位矢量(长度为1的向量)。
V1(1 / 5.1,5 / 5.1)= V1(0.2,0.98)
长度计算矢量4
现在V1乘以你想要的长度,例如4,拿到佛蒙特州
VT(0.2 * 4,0.98 * 4)= VT(0.8,3.92)
计算目标点 添加矢量Vt的A点得到点T(目标)。
T = A + VT = T(1.8,2.92)
编辑:回答你的修改 该方法LengthOfHypotenuse应该看起来像在计算BSQ固定错误和去除多余Math.Abs打电话,因为2战俘总是正删除加入0.5,不知道你为什么会需要一个 你至少应该用一个浮点数作为返回值(双精度或十进制也将工作)
//您应该Vector2类,而不是点工作,并利用自己的长度属性私人双LengthOfHypotenuse(A点,B点){
双ASQ = Math.Pow(a.X
b.X,2); //水平长度的平方
双BSQ = Math.Pow(a.Y
b.Y,2); //垂直长度的平方
返回的Math.sqrt(ASQ + BSQ); //斜边长度}
该方法绘制(A点,B点)应该看起来像: 修正DrawCell()调用 私人无效抽奖(A点,B点){
双maxDistance = LengthOfHypotenuse(A,B);
对于(INT距离= 0;距离和LT; maxDistance ++距离){
VAR点= CalculatePoint(新Vector2(一),新Vector2(二),距离);
DrawCell(point.X,point.Y,_theLineBrush);
您CalculatePoint(A点,B点,INT距离)方法: 动了一些计算到Vector2类 私有点CalculatePoint(Vector2一,Vector2 B,INT距离){
Vector2 vectorAB =一 -
返回+ vectorAB.UnitVector *距离;}
我已经扩展了Vector类为您丢失的运营商(学分AgentFire)添加
// AgentFire:更好的方法(你可以,如果你需要重命名结构):
结构Vector2 {
公共只读双X;
公共只读双Y;
公共Vector2(点P):这个(p.X,p.Y){
公共Vector2(双X,双Y){
this.X = X;
this.Y = Y;
公共静态Vector2运营商 - (Vector2一,Vector2 B){
返回新Vector2(b.X
公共静态Vector2运营商+(Vector2一,Vector2 B){
返回新Vector2(b.X + a.X,b.Y + a.Y);
公共静态Vector2符*(Vector2一,双D){
返回新Vector2(a.X * D,a.Y * D);
公共静态Vector2运营商/(Vector2一,双D){
返回新Vector2(a.X次/ d,a.Y /天);
公共静态隐运营商角度(Vector2一){
返回新的点((INT)a.X,(INT)a.Y);
公共Vector2 UnitVector {
{返回本/长; }
公共双长度{
双ASQ = Math.Pow(x,2);
双BSQ = Math.Pow(Y,2);
返回的Math.sqrt(ASQ + BSQ);
公共重写字符串的ToString(){
返回的String.Format(“[{0},{1}]”,X,Y);
本文地址: &
扫一扫关注官方微信

我要回帖

更多关于 matlab数值计算 的文章

 

随机推荐