using System; using System.Drawing; using System.Windows.Forms; namespace CutLine { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } } static public class ai { static byte code(Point p, Rectangle rec) { ; ; ; ; ; return ans; } static public void run(Point from, Point to, Rectangle rec) { byte f = code(from, rec); byte t = code(to, rec); )//绝对无交集,两点在同一侧 { nothing = true; return; } )//两点都在内部 { ai.from = from; ai.to = to; nothing = false; return; } ) { change(ref to,ref from,ref rec,ref t); } else{ change(ref from,ref to, ref rec,ref f); } run(from, to, rec); } static void change(ref Point move, ref Point stay, ref Rectangle rec,ref byte c) { ) != ) { move.X =(int)( (move.X - stay.X) *(double) (rec.Y - stay.Y) / (move.Y - stay.Y) + stay.X); move.Y = rec.Y; } ) != ) { move.X = (int)((double)(move.X - stay.X) / (move.Y - stay.Y) * (rec.Y + rec.Height - stay.Y) + stay.X); move.Y = rec.Y + rec.Height; } ) != ) { move.Y = (int )((double)(move.Y - stay.Y) / (move.X - stay.X) * (rec.X - stay.X) + stay.Y); move.X = rec.X; } ) != ) { move.Y = (int)((double)(move.Y - stay.Y) / (move.X - stay.X) * (rec.X +rec.Width- stay.X) + stay.Y); move.X = rec.X+rec.Width; } } ,); ,); public static bool nothing = true; } public partial class Form1 : Form { public Form1() { InitializeComponent(); Text = "直线裁剪--made by weidiao.neu"; } ; Point from = new Point(); Point to = new Point(); Point temp = new Point(); Rectangle rec = new Rectangle(); private void button1_Click(object sender, EventArgs e) { CreateGraphics().Clear(Color.AliceBlue); times = ; } bool bigger(Point a, Point b) { return a.X >= b.X && b.X >= b.Y; } int min(int a, int b) { if(a<b)return a; return b; } Pen linePen = ); Pen recPen = ); override protected void OnMouseMove(MouseEventArgs e) { || times == ) return; Bitmap bit = new Bitmap(ClientSize.Width, ClientSize.Height); Graphics g = Graphics.FromImage(bit); g.Clear(Color.AliceBlue); switch (times) { : g.DrawLine(linePen, from, e.Location); break; : g.DrawLine(linePen, from, to); rec.X = min(temp.X, e.X); rec.Y = min(temp.Y, e.Y); rec.Width = Math.Abs(temp.X - e.X); rec.Height = Math.Abs(temp.Y - e.Y); g.DrawRectangle(recPen, rec); break; } CreateGraphics().DrawImage(bit, , ); } override protected void OnMouseDown(MouseEventArgs e) { switch (times) { : button1_Click(null, null); from.X = e.X; from.Y = e.Y; break; : to.X = e.X; to.Y = e.Y; CreateGraphics().DrawLine(linePen, from, to); break; : temp.X = e.X; temp.Y = e.Y; break; : rec.X = min(temp.X, e.X); rec.Y = min(temp.Y, e.Y); rec.Width = Math.Abs(temp.X - e.X); rec.Height = Math.Abs(temp.Y - e.Y); CreateGraphics().DrawRectangle(recPen, rec); ai.run(from, to, rec); if(ai.nothing==false) CreateGraphics().DrawLine(), ai.from, ai.to); break; } times++; times %= ; } } }
java
package mySecondPackage; import java.awt.*; import java.awt.event.*; import java.awt.image.BufferedImage; import javax.swing.*; /* * 上下左右 * 0000 * 用4位二进制表示 * 上边之外为1,也就是上边之上为1 * 下边之外为1,也就是下边之下为1 * 左边之外为1,也就是左边之左为1 * 右边之外为1,也就是右边之右为1 * */ /** * @author weidiao * @see hahaha * @version 2.0 */ class ai { /** * 按照上下左右的顺序进行编码 * */ static byte code(Point p, Rectangle rec) { byte ans = 0; if (p.y < rec.y)// 如果点p在长方形的上边 ans |= 1; else if (p.y > rec.y + rec.height)// 如果点p在长方形的下边 ans |= 2; if (p.x < rec.x)// 如果点p在长方形左边 ans |= 4; else if (p.x > rec.x + rec.width)// 如果点p在长方形右边 ans |= 8; return ans; } /** * @算法的主体,进行判断和循环 * @param 输入参数 * :Point from,to描述直线 Rectangle rec描述矩形 * @return输出参数:返回为空,因为Point from和to是传引用,所以就直接改变了 * 类的静态变量nothing反映了是否产生了结果,若无交点,nothing=true */ static public void run(Point from, Point to, Rectangle rec) { while (true) { byte f = code(from, rec); byte t = code(to, rec);// 对两个点进行编码 if ((f & t) != 0)// 绝对无交集,两点在矩形某条边同一侧 { nothing = true;// return; } if ((f | t) == 0)// 两点都在矩形内部 { nothing = false; return; } if (f == 0) change(to, from, rec, t); else change(from, to, rec, f); } } /** * @本函数用于求直线与矩形边所在直线的交点 * @param Point * move表示准备移动的那个点,Point stay表示不移动的点 Rectangle rec表示矩形 Byte c * 表示准备移动的那个点的编码 * @return 被移动的点move值将会发生变化 * @难点在于:计算时要用浮点数进行计算,直接用int误差太大 */ static void change(Point move, Point stay, Rectangle rec, byte c) { if ((c & 1) != 0) { move.x = (int) ((move.x - stay.x) * (double) (rec.y - stay.y) / (move.getY() - stay.y) + stay.x); move.y = rec.y; } else if ((c & 2) != 0) { move.x = (int) ((double) (move.x - stay.x) / (move.y - stay.y) * (rec.y + rec.height - stay.y) + stay.x); move.y = rec.y + rec.height; } else if ((c & 4) != 0) { move.y = (int) ((double) (move.y - stay.y) / (move.x - stay.x) * (rec.x - stay.x) + stay.y); move.x = rec.x; } else if ((c & 8) != 0) { move.y = (int) ((double) (move.y - stay.y) / (move.x - stay.x) * (rec.x + rec.width - stay.x) + stay.y); move.x = rec.x + rec.width; } } public static boolean nothing = true; } /** * @CutLine类,界面部分 * */ class CutLine extends JFrame { public static void main(String[] args) { new CutLine(); } public CutLine() { setTitle("直线裁剪--made by weidiao.neu"); setSize(700, 700); setVisible(true); setLayout(null); setDefaultCloseOperation(EXIT_ON_CLOSE); JButton clearButton = new JButton("清屏"); clearButton.setFont(new Font("楷体", Font.BOLD, 50)); clearButton.addActionListener(clearButtonClick); clearButton.setLocation(500, 500); clearButton.setSize(200, 200); add(clearButton); addMouseListener(mouse); addMouseMotionListener(mouseMotion); } int times = 0; Point from = new Point(); Point to = new Point(); Point temp = new Point();// 用于存储矩形左上角的位置 Rectangle rec = new Rectangle(); ActionListener clearButtonClick = new ActionListener() { public void actionPerformed(ActionEvent e) { getGraphics().clearRect(0, 0, getWidth(), getHeight()); times = 0; } }; MouseListener mouse = new MouseAdapter() { public void mouseClicked(MouseEvent e) { switch (times) { case 0: clearButtonClick.actionPerformed(null); from = e.getPoint(); break; case 1: to = e.getPoint(); getGraphics().drawLine(from.x, from.y, to.x, to.y); break; case 2: temp = e.getPoint(); break; case 3: rec.x = Integer.min(temp.x, e.getX()); rec.y = Integer.min(temp.y, e.getY()); rec.width = Math.abs(temp.x - e.getX()); rec.height = Math.abs(temp.y - e.getY()); getGraphics().drawRect(rec.x, rec.y, rec.width, rec.height); ai.run(from, to, rec); if (ai.nothing == false) { Graphics2D g = (Graphics2D) getGraphics(); g.setStroke(new BasicStroke(4)); g.setColor(Color.red); g.drawLine(from.x, from.y, to.x, to.y); } break; } times++; if (times == 4) times = 0; } }; MouseMotionListener mouseMotion = new MouseMotionAdapter() { public void mouseMoved(MouseEvent e) { if (times == 0 || times == 2) return; getGraphics().clearRect(0, 0, getWidth(), getHeight()); BufferedImage bit = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB_PRE); Graphics2D g = (Graphics2D) bit.getGraphics(); switch (times) { case 1: g.setColor(Color.blue); g.setStroke(new BasicStroke(3)); g.drawLine(from.x, from.y, e.getX(), e.getY()); break; case 3: g.setColor(Color.blue); g.setStroke(new BasicStroke(3)); g.drawLine(from.x, from.y, to.x, to.y); rec.x = Integer.min(temp.x, e.getX()); rec.y = Integer.min(temp.y, e.getY()); rec.width = Math.abs(temp.x - e.getX()); rec.height = Math.abs(temp.y - e.getY()); g.drawRect(rec.x, rec.y, rec.width, rec.height); break; } getGraphics().drawImage(bit, 0, 0, null); } }; boolean bigger(Point a, Point b) { return a.x >= b.x && b.x >= b.y; } }