请教一下:C#如何实现在一个矩形框内四次反射

bluespray 2008-04-10 09:25:38
假如一个坐标分别为A(171,145),B(853,145),C(853,473),D(171,473)组成的矩形,在矩形中任意指定一点O,鼠标P在矩形框中移动时自动生成以OP为最初入射线矩形边为水平面的反射线PQ,然后再以PQ为入射线,以此类推,实现四次以上的反射线条,请问如何实现?分不够再加,希望您能指点,谢谢

说明:O点是任意指定的,P是随鼠标移动动态变化的,生成线条也是动态变化的
...全文
217 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
wxj56030210 2010-01-14
  • 打赏
  • 举报
回复
有用
yagebu1983 2008-07-14
  • 打赏
  • 举报
回复
收藏!!
bluespray 2008-04-11
  • 打赏
  • 举报
回复
写得很好,算法很清晰
bluespray 2008-04-11
  • 打赏
  • 举报
回复
非常感谢
蝶恋花雨 2008-04-10
  • 打赏
  • 举报
回复
已经帮你呼他了
Magic_YJL 2008-04-10
  • 打赏
  • 举报
回复
帮顶了
gomoku 2008-04-10
  • 打赏
  • 举报
回复
窗口程序本身不复杂,关键是判断射线是否和特定线段相交,如果相交如何计算反射角等。

所附的代码可以直接编译和运行,供你参考和讨论。我没有写很多注释,如果你对向量几何熟悉的话,所附代码你应该可以看的很清楚。
如果你不熟悉的话,我三言两语也说不清楚,你可以边看书边参考代码。

代码分两部分,Form1.cs(窗口类) 和 Geometry.cs(几何辅助类),你可以建C#工程或用此命令行编译:
csc.exe /t:winexe Form1.cs Geometry.cs

Form1.cs

// Form1.cs
//
// compile with: csc /t:winexe Form1.cs Geometry.cs
using System;
using System.Drawing;
using System.Windows.Forms;

public class Form1 : Form
{
static void Main()
{
Application.Run(new Form1());
}
public Form1()
{
this.Size = new Size(1000, 600);
lines[0] = new Line(A, B);
lines[1] = new Line(B, C);
lines[2] = new Line(C, D);
lines[3] = new Line(D, A);
}
protected override void OnMouseMove(MouseEventArgs e)
{
P = new Vec2(e.X, e.Y);
Invalidate();
}
protected override void OnPaint(PaintEventArgs e)
{
foreach (Line l in lines)
{
l.DrawTo(e.Graphics);
}

Vec2 start = O;
Vec2 end = P - O;
for (int i = 0; i < 4; i++)
{
Line line = Bump(ref start, ref end);
line.DrawTo(e.Graphics, new Pen(Color.FromArgb(i * 40, i * 50, i * 60)));
}
}

// Test whether an array hits the line, also calculate the length of the ray when hit
bool Shoot(Vec2 start, Vec2 dir, Line line, ref float hit)
{
Vec2 n = line.Normal();
float denom = n * dir;
if (Math.Abs(denom) > 1.0E-32)
{
hit = n * (line.p1 - start) / denom;
}
return denom < 0.0f;
}

// Get the line up to the boundary. Reflected line (start point + direction) is calculated.
Line Bump(ref Vec2 start, ref Vec2 dir)
{
int hitLine = -1;
float hit = 0, miniHit = 1.0E+32F;
for (int i = 0; i < lines.Length; i++)
{
if (Shoot(start, dir, lines[i], ref hit))
{
if (hit > 0 && hit < miniHit)
{
miniHit = hit;
hitLine = i;
}
}
}
if (hitLine >= 0)
{
Line ray = new Line(start, start + dir * miniHit);

// calculate the reflection
Vec2 n = lines[hitLine].Normal();
float d = dir * n;
n = n * d * 2;

start = start + dir * miniHit;
dir = dir - n;
return ray;
}
return new Line(start, dir);
}

Vec2 A = new Vec2(171, 145);
Vec2 B = new Vec2(853, 145);
Vec2 C = new Vec2(853, 473);
Vec2 D = new Vec2(171, 473);

Vec2 O = new Vec2(300, 300);
Vec2 P = new Vec2(306, 308);

Line[] lines = new Line[4];
}



Geometry.cs

// Geometry.cs
//
using System;
using System.Drawing;

// representation of a point, or a 2D vector
class Vec2
{
public Vec2()
{
}
public Vec2(float x, float y)
{
this.x = x;
this.y = y;
}
public float Length()
{
return (float)Math.Sqrt(x * x + y * y);
}
public static Vec2 operator +(Vec2 v1, Vec2 v2)
{
return new Vec2(v1.x + v2.x, v1.y + v2.y);
}
public static Vec2 operator -(Vec2 v1, Vec2 v2)
{
return new Vec2(v1.x - v2.x, v1.y - v2.y);
}
public static Vec2 operator *(Vec2 v1, float scale)
{
return new Vec2(v1.x * scale, v1.y * scale);
}
public static Vec2 operator /(Vec2 v1, float scale)
{
return new Vec2(v1.x / scale, v1.y / scale);
}
public static Vec2 operator !(Vec2 v)
{
// pert() operation: get a vector that is orthogonal to this vector
return new Vec2(-v.y, v.x);
}
public static float operator *(Vec2 v1, Vec2 v2)
{
// dot product
return v1.x * v2.x + v1.y * v2.y;
}
public float x, y;
}

// representation of a line
class Line
{
public Line(Vec2 p1, Vec2 p2)
{
this.p1 = p1;
this.p2 = p2;
}
public Vec2 Normal()
{
Vec2 v = p2 - p1;
return !v / v.Length();
}
public float Length()
{
return (p2 - p1).Length();
}
public void DrawTo(Graphics g, Pen p)
{
g.DrawLine(p, p1.x, p1.y, p2.x, p2.y);
}
public void DrawTo(Graphics g)
{
DrawTo(g, Pens.Black);
}

public Vec2 p1, p2;
}

110,577

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧