C# 实现线段的编码裁剪算法(vs2010)
1 using System; 2 3 using System.Collections.Generic; 4 5 using System.ComponentModel; 6 7 using System.Data; 8 9 using System.Drawing; 10 11 using System.Linq; 12 13 using System.Text; 14 15 using System.Windows.Forms; 16 17 18 19 namespace cutLine 20 21 { 22 23 unsafe public partial class Form1 : Form 24 25 { 26 27 const int left = 1; 28 29 const int right = 2; 30 31 const int bottom = 4; 32 33 const int top = 8; 34 35 Point window1, window2; //保存裁剪区矩形 36 37 Point line1, line2; //保存线段的两个端点坐标 38 39 int start, x , y; //标志点击次数,取值范围0,1,2 40 41 Graphics g; //GDI 对象 42 43 44 45 public Form1() 46 47 { 48 49 InitializeComponent(); 50 51 g = CreateGraphics(); 52 53 window1 = new Point(120, 120);//裁剪区左下角 54 55 window2 = new Point(600, 420); //裁剪区右上角 56 57 start = 0; 58 59 } 60 61 62 63 private void Form1_MouseClick(object sender, MouseEventArgs e) 64 65 { 66 67 int x = e.X, y = e.Y; //记录鼠标点击位置: 68 69 Pen p = new Pen(Brushes.Black, 1); 70 71 switch (start) 72 73 { 74 75 case 0: 76 77 { 78 79 g.Clear(Color.Silver); 80 81 Background(); 82 83 start = 1; 84 85 line1 = new Point(e.X, e.Y); 86 87 g.DrawRectangle(Pens.Black, x - 2, y - 2, 2, 2); //画一个小方块,显示点击位置 88 89 break; 90 91 } 92 93 case 1: 94 95 { 96 97 start = 0; 98 99 line2 = new Point(e.X, e.Y); 100 101 g.DrawRectangle(Pens.Black, x - 2, y - 2, 2, 2); //画一个小方块,显示点击位置 102 103 g.DrawLine(p, line1, line2); 104 105 //DrawString_1(); 106 107 cutLine(line1, line2, window1.X, window2.X, window1.Y, window2.Y); 108 109 break; 110 111 } 112 113 } 114 115 } 116 117 118 119 private void Background() 120 121 { 122 123 if (start == 0) 124 125 g.DrawRectangle(Pens.Black, window1.X, window1.Y,window2.X - window1.X, window2.Y - window1.Y); 126 127 DrawString(); 128 129 } 130 131 132 133 private void DrawString() 134 135 { 136 137 String str; 138 139 str = " 黑色矩形为裁剪窗口\n 点鼠标输入线段的两个点,自动执行裁剪\n 红色为线段裁剪后的部分"; //临时字体对象 //画刷枚举 //位置 140 141 g.DrawString(str, new Font("宋体", 16, FontStyle.Regular), Brushes.Black, 20, 20); 142 143 } 144 145 146 147 private void DrawString_1(int code1, int code2) 148 149 { 150 151 String str; 152 153 g.FillRectangle (Brushes.White, 120, 40, 190, 30); 154 155 str = "\n编码: " Convert.ToString(code1, 2).PadLeft(4, ’’0’’) " " Convert.ToString(code2, 2).PadLeft(4, ’’0’’); 156 157 g.DrawString(str, new Font("宋体", 16, FontStyle.Regular), Brushes.Black, 120, 20); 158 159 } 160 161 162 163 private void Form1_Load(object sender, EventArgs e) 164 165 { 166 167 } 168 169 170 171 private void Form1_Paint(object sender, PaintEventArgs e) 172 173 { 174 175 Background(); 176 177 } 178 179 private void Encode(int x, int y,int *code,int xl, int xr, int yb, int yt) 180 181 { 182 183 int c = 0; 184 185 if (x < xl) 186 187 c = c | left; 188 189 else if (x > xr) 190 191 c = c | right; 192 193 if (y < yb) 194 195 c = c | bottom; 196 197 else if (y > yt) 198 199 c = c | top; 200 201 (*code) = c; 202 203 } 204 205 public void cutLine(Point p1, Point p2, int xl, int xr, int yb, int yt) 206 207 { 208 209 Pen p = new Pen(Brushes.Red, 2); 210 211 int x1, x2, y1, y2,code1, code2, code; 212 213 x1 = p1.X; x2 = p2.X; y1 = p1.Y; y2 = p2.Y; 214 215 Encode(x1,y1, &code1, xl,xr,yb,yt); 216 217 Encode(x2,y2, &code2, xl,xr,yb,yt); 218 219 DrawString_1(code1, code2); 220 221 while (code1 != 0 || code2 != 0) 222 223 { 224 225 if ((code1 & code2) != 0) return; 226 227 code = code1; 228 229 if (code1 == 0) 230 231 code = code2; 232 233 if ((left & code) != 0)//线段与左边界相交 234 235 { 236 237 x = xl; 238 239 y = y1 (y2 - y1) * (xl - x1) / (x2 - x1); 240 241 } 242 243 else if ((right & code) != 0)//线段与右边界相交 244 245 { 246 247 x = xr; 248 249 y = y1 (y2 - y1) * (xr - x1) / (x2 - x1); 250 251 } 252 253 else if ((bottom & code) != 0)//线段与下边界相交 254 255 { 256 257 y = yb; 258 259 x = x1 (x2 - x1) * (yb - y1) / (y2 - y1); 260 261 } 262 263 else if ((top & code) != 0)//线段与上边界相交 264 265 { 266 267 y = yt; 268 269 x = x1 (x2 - x1) * (yt - y1) / (y2 - y1); 270 271 } 272 273 if (code == code1) 274 275 { 276 277 x1 = x; 278 279 y1 = y; 280 281 Encode(x, y, &code1, xl, xr, yb, yt); 282 283 } 284 285 else 286 287 { 288 289 x2 = x; 290 291 y2 = y; 292 293 Encode(x, y, &code2, xl, xr, yb, yt); 294 295 } 296 297 } 298 299 p1.X = x1; p1.Y = y1; 300 301 p2.X = x2; p2.Y = y2; 302 303 g.DrawLine(p, p1, p2); 304 305 } 306 307 } 308 309 }
作者:Standby — 一生热爱名山大川、草原沙漠,还有我们小郭宝贝!
出处:http://www.cnblogs.com/standby/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://www.cnblogs.com/standby/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。