1 using System; 2 using System.Drawing; 3 using System.Windows.Forms; 4 5 namespace CutLine 6 { 7 static class Program 8 { 9 [STAThread] 10 static void Main() 11 { 12 Application.EnableVisualStyles(); 13 Application.SetCompatibleTextRenderingDefault(false); 14 Application.Run(new Form1()); 15 } 16 } 17 static public class ai 18 { 19 static byte code(Point p, Rectangle rec) 20 { 21 byte ans=0; 22 if (p.Y < rec.Y) ans |= 1; 23 if (p.Y > rec.Y + rec.Height) ans |= 2; 24 if (p.X < rec.X) ans |= 4; 25 if (p.X > rec.X + rec.Width) ans |= 8; 26 return ans; 27 } 28 static public void run(Point from, Point to, Rectangle rec) 29 { 30 byte f = code(from, rec); 31 byte t = code(to, rec); 32 if ((f & t) != 0)//绝对无交集,两点在同一侧 33 { 34 nothing = true; 35 return; 36 } 37 if ((f | t)== 0)//两点都在内部 38 { 39 ai.from = from; 40 ai.to = to; 41 nothing = false; 42 return; 43 } 44 if (f == 0) 45 { 46 change(ref to,ref from,ref rec,ref t); 47 } 48 else{ 49 change(ref from,ref to, ref rec,ref f); 50 } 51 run(from, to, rec); 52 } 53 static void change(ref Point move, ref Point stay, ref Rectangle rec,ref byte c) 54 { 55 if ((c & 1) != 0) 56 { 57 move.X =(int)( (move.X - stay.X) *(double) (rec.Y - stay.Y) / (move.Y - stay.Y) + stay.X); 58 move.Y = rec.Y; 59 } 60 else if ((c & 2) != 0) 61 { 62 move.X = (int)((double)(move.X - stay.X) / (move.Y - stay.Y) * (rec.Y + rec.Height - stay.Y) + stay.X); 63 move.Y = rec.Y + rec.Height; 64 } 65 else if ((c & 4) != 0) 66 { 67 move.Y = (int )((double)(move.Y - stay.Y) / (move.X - stay.X) * (rec.X - stay.X) + stay.Y); 68 move.X = rec.X; 69 } 70 else if ((c & 8) != 0) 71 { 72 move.Y = (int)((double)(move.Y - stay.Y) / (move.X - stay.X) * (rec.X +rec.Width- stay.X) + stay.Y); 73 move.X = rec.X+rec.Width; 74 } 75 } 76 public static Point from = new Point(10,10); 77 public static Point to = new Point(40,40); 78 public static bool nothing = true; 79 } 80 public partial class Form1 : Form 81 { 82 public Form1() 83 { 84 InitializeComponent(); 85 Text = "直线裁剪--made by weidiao.neu"; 86 } 87 88 int times = 0; 89 Point from = new Point(); 90 Point to = new Point(); 91 Point temp = new Point(); 92 Rectangle rec = new Rectangle(); 93 94 private void button1_Click(object sender, EventArgs e) 95 { 96 CreateGraphics().Clear(Color.AliceBlue); 97 times = 0; 98 } 99 bool bigger(Point a, Point b) 100 { 101 return a.X >= b.X && b.X >= b.Y; 102 } 103 int min(int a, int b) 104 { 105 if(a<b)return a; 106 return b; 107 } 108 Pen linePen = new Pen(Color.Red, 5); 109 Pen recPen = new Pen(Color.Purple, 2); 110 override protected void OnMouseMove(MouseEventArgs e) 111 { 112 if (times == 0 || times == 2) return; 113 Bitmap bit = new Bitmap(ClientSize.Width, ClientSize.Height); 114 Graphics g = Graphics.FromImage(bit); 115 g.Clear(Color.AliceBlue); 116 switch (times) 117 { 118 case 1: g.DrawLine(linePen, from, e.Location); 119 break; 120 case 3: g.DrawLine(linePen, from, to); 121 rec.X = min(temp.X, e.X); 122 rec.Y = min(temp.Y, e.Y); 123 rec.Width = Math.Abs(temp.X - e.X); 124 rec.Height = Math.Abs(temp.Y - e.Y); 125 g.DrawRectangle(recPen, rec); 126 break; 127 } 128 CreateGraphics().DrawImage(bit, 0, 0); 129 } 130 override protected void OnMouseDown(MouseEventArgs e) 131 { 132 switch (times) 133 { 134 case 0: 135 button1_Click(null, null); 136 from.X = e.X; 137 from.Y = e.Y; 138 break; 139 case 1: to.X = e.X; 140 to.Y = e.Y; 141 CreateGraphics().DrawLine(linePen, from, to); 142 break; 143 case 2: temp.X = e.X; 144 temp.Y = e.Y; 145 break; 146 case 3: 147 rec.X = min(temp.X, e.X); 148 rec.Y = min(temp.Y, e.Y); 149 rec.Width = Math.Abs(temp.X - e.X); 150 rec.Height = Math.Abs(temp.Y - e.Y); 151 CreateGraphics().DrawRectangle(recPen, rec); 152 ai.run(from, to, rec); 153 if(ai.nothing==false) 154 CreateGraphics().DrawLine(new Pen(Color.Green, 8), ai.from, ai.to); 155 break; 156 } 157 times++; 158 times %= 4; 159 } 160 } 161 }
java
1 package mySecondPackage; 2 3 import java.awt.*; 4 import java.awt.event.*; 5 import java.awt.image.BufferedImage; 6 7 import javax.swing.*; 8 9 /* 10 * 上下左右 11 * 0000 12 * 用4位二进制表示 13 * 上边之外为1,也就是上边之上为1 14 * 下边之外为1,也就是下边之下为1 15 * 左边之外为1,也就是左边之左为1 16 * 右边之外为1,也就是右边之右为1 17 * */ 18 /** 19 * @author weidiao 20 * @see hahaha 21 * @version 2.0 22 */ 23 24 class ai { 25 /** 26 * 按照上下左右的顺序进行编码 27 * */ 28 static byte code(Point p, Rectangle rec) { 29 byte ans = 0; 30 if (p.y < rec.y)// 如果点p在长方形的上边 31 ans |= 1; 32 else if (p.y > rec.y + rec.height)// 如果点p在长方形的下边 33 ans |= 2; 34 if (p.x < rec.x)// 如果点p在长方形左边 35 ans |= 4; 36 else if (p.x > rec.x + rec.width)// 如果点p在长方形右边 37 ans |= 8; 38 return ans; 39 } 40 41 /** 42 * @算法的主体,进行判断和循环 43 * @param 输入参数 44 * :Point from,to描述直线 Rectangle rec描述矩形 45 * @return输出参数:返回为空,因为Point from和to是传引用,所以就直接改变了 46 * 类的静态变量nothing反映了是否产生了结果,若无交点,nothing=true 47 */ 48 static public void run(Point from, Point to, Rectangle rec) { 49 while (true) { 50 byte f = code(from, rec); 51 byte t = code(to, rec);// 对两个点进行编码 52 53 if ((f & t) != 0)// 绝对无交集,两点在矩形某条边同一侧 54 { 55 nothing = true;// 56 return; 57 } 58 if ((f | t) == 0)// 两点都在矩形内部 59 { 60 nothing = false; 61 return; 62 } 63 if (f == 0) 64 change(to, from, rec, t); 65 else 66 change(from, to, rec, f); 67 68 } 69 } 70 71 /** 72 * @本函数用于求直线与矩形边所在直线的交点 73 * @param Point 74 * move表示准备移动的那个点,Point stay表示不移动的点 Rectangle rec表示矩形 Byte c 75 * 表示准备移动的那个点的编码 76 * @return 被移动的点move值将会发生变化 77 * @难点在于:计算时要用浮点数进行计算,直接用int误差太大 78 */ 79 static void change(Point move, Point stay, Rectangle rec, byte c) { 80 if ((c & 1) != 0) { 81 move.x = (int) ((move.x - stay.x) * (double) (rec.y - stay.y) 82 / (move.getY() - stay.y) + stay.x); 83 move.y = rec.y; 84 } else if ((c & 2) != 0) { 85 move.x = (int) ((double) (move.x - stay.x) / (move.y - stay.y) 86 * (rec.y + rec.height - stay.y) + stay.x); 87 move.y = rec.y + rec.height; 88 } else if ((c & 4) != 0) { 89 move.y = (int) ((double) (move.y - stay.y) / (move.x - stay.x) 90 * (rec.x - stay.x) + stay.y); 91 move.x = rec.x; 92 } else if ((c & 8) != 0) { 93 move.y = (int) ((double) (move.y - stay.y) / (move.x - stay.x) 94 * (rec.x + rec.width - stay.x) + stay.y); 95 move.x = rec.x + rec.width; 96 } 97 } 98 99 public static boolean nothing = true; 100 } 101 102 /** 103 * @CutLine类,界面部分 104 * */ 105 class CutLine extends JFrame { 106 public static void main(String[] args) { 107 new CutLine(); 108 } 109 110 public CutLine() { 111 setTitle("直线裁剪--made by weidiao.neu"); 112 setSize(700, 700); 113 setVisible(true); 114 setLayout(null); 115 setDefaultCloseOperation(EXIT_ON_CLOSE); 116 117 118 JButton clearButton = new JButton("清屏"); 119 clearButton.setFont(new Font("楷体", Font.BOLD, 50)); 120 clearButton.addActionListener(clearButtonClick); 121 clearButton.setLocation(500, 500); 122 clearButton.setSize(200, 200); 123 add(clearButton); 124 125 addMouseListener(mouse); 126 addMouseMotionListener(mouseMotion); 127 128 } 129 130 int times = 0; 131 Point from = new Point(); 132 Point to = new Point(); 133 Point temp = new Point();// 用于存储矩形左上角的位置 134 Rectangle rec = new Rectangle(); 135 136 ActionListener clearButtonClick = new ActionListener() { 137 public void actionPerformed(ActionEvent e) { 138 getGraphics().clearRect(0, 0, getWidth(), getHeight()); 139 times = 0; 140 } 141 }; 142 143 MouseListener mouse = new MouseAdapter() { 144 public void mouseClicked(MouseEvent e) { 145 switch (times) { 146 case 0: 147 clearButtonClick.actionPerformed(null); 148 from = e.getPoint(); 149 break; 150 case 1: 151 to = e.getPoint(); 152 getGraphics().drawLine(from.x, from.y, to.x, to.y); 153 break; 154 case 2: 155 temp = e.getPoint(); 156 break; 157 case 3: 158 rec.x = Integer.min(temp.x, e.getX()); 159 rec.y = Integer.min(temp.y, e.getY()); 160 rec.width = Math.abs(temp.x - e.getX()); 161 rec.height = Math.abs(temp.y - e.getY()); 162 getGraphics().drawRect(rec.x, rec.y, rec.width, rec.height); 163 ai.run(from, to, rec); 164 if (ai.nothing == false) { 165 Graphics2D g = (Graphics2D) getGraphics(); 166 g.setStroke(new BasicStroke(4)); 167 g.setColor(Color.red); 168 g.drawLine(from.x, from.y, to.x, to.y); 169 } 170 break; 171 } 172 times++; 173 if (times == 4) 174 times = 0; 175 } 176 }; 177 MouseMotionListener mouseMotion = new MouseMotionAdapter() { 178 public void mouseMoved(MouseEvent e) { 179 if (times == 0 || times == 2) 180 return; 181 getGraphics().clearRect(0, 0, getWidth(), getHeight()); 182 183 BufferedImage bit = new BufferedImage(getWidth(), getHeight(), 184 BufferedImage.TYPE_INT_ARGB_PRE); 185 Graphics2D g = (Graphics2D) bit.getGraphics(); 186 switch (times) { 187 case 1: 188 g.setColor(Color.blue); 189 g.setStroke(new BasicStroke(3)); 190 g.drawLine(from.x, from.y, e.getX(), e.getY()); 191 break; 192 case 3: 193 g.setColor(Color.blue); 194 g.setStroke(new BasicStroke(3)); 195 g.drawLine(from.x, from.y, to.x, to.y); 196 rec.x = Integer.min(temp.x, e.getX()); 197 rec.y = Integer.min(temp.y, e.getY()); 198 rec.width = Math.abs(temp.x - e.getX()); 199 rec.height = Math.abs(temp.y - e.getY()); 200 g.drawRect(rec.x, rec.y, rec.width, rec.height); 201 break; 202 } 203 getGraphics().drawImage(bit, 0, 0, null); 204 } 205 }; 206 207 boolean bigger(Point a, Point b) { 208 return a.x >= b.x && b.x >= b.y; 209 } 210 }