zoukankan      html  css  js  c++  java
  • 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 = "                              黑色矩形为裁剪窗口
                                  点鼠标输入线段的两个点,自动执行裁剪
                                  红色为线段裁剪后的部分";     //临时字体对象              //画刷枚举     //位置
    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 = "
    编码: "   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/

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

  • 相关阅读:
    视频直播架构
    day1 python 入门
    python 多用户登录
    mysql innobackup 备份脚本
    ADT离线安装
    真机调试adb:wait for device 解决方案
    php中的魔术方法
    整理资料
    PostgreSQL表空间_数据库_模式_表_用户角色之间的关系[转]
    PHP获取文件夹的大小
  • 原文地址:https://www.cnblogs.com/standby/p/4150145.html
Copyright © 2011-2022 走看看