C# Cut Line Bressenham Algorithm

  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 }
原文地址:https://www.cnblogs.com/weiyinfu/p/4986969.html