ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

权属面积批量修改0.1

2021-06-27 00:00:53  阅读:219  来源: 互联网

标签:angle 批量 point 0.1 list coordinates Polyline 权属 math


import win32com.client
import pythoncom
import tkinter as tk
from tkinter import messagebox
import numpy
import math
'''打开选择文件夹对话框'''
window = tk.Tk()
window.title("权属面积批量修改0.1")
window.geometry('380x30+800+200')  # 290 160为窗口大小,+1000 +10 定义窗口弹出时的默认展示位置

window.resizable(0, 0)
window['background'] = 'DimGray'


def vtpnt(x, y, z=0):
    """坐标点转化为浮点数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, (x, y, z))


def vtobj(obj):
    """转化为对象数组"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_DISPATCH, obj)


def vtFloat(list):
    """列表转化为浮点数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_R8, list)


def vtInt(list):
    """列表转化为整数"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_I2, list)


def vtVariant(list):
    """列表转化为变体"""
    return win32com.client.VARIANT(pythoncom.VT_ARRAY | pythoncom.VT_VARIANT, list)


def list_format_conversion(old_list, leixing=False, step=2, deduction=None):
    if leixing is False:
        leixing = list
    else:
        leixing = tuple
    new_list = []
    for counte in range(0, len(old_list), step):
        new_list.append(leixing(old_list[counte:counte + step])[:deduction])
    return new_list


'''
进位,返回str
'''


def rrd(point, f):
    if f == 0:
        point = str(int(point))
    elif f > 0:
        SP = str(numpy.around(point, f))
        sy = SP.split(".")
        n = len(sy[1])
        if n < f:
            sj = f - n
            point = sy[0] + "." + sy[1] + "0" * sj
        else:
            point = SP
    elif f < 0:
        tk.messagebox.showinfo('提示', "取位不可为负")
    return point


'''
计算顺时针或逆时针
green方法判断面积正负
'''


def polyline_order(P):
    n = len(P)
    P.append(P[0])
    S = 0
    for i in range(0, n):
        S = S + (P[i][0] + P[i + 1][0]) * (P[i + 1][1] - P[i][1])
    if S > 0:
        return False  # 逆时针
    else:
        return True  # 顺时针


def compute_polygon_area(points):
    point_num = len(points)
    if (point_num < 3): return 0.0
    s = points[0][1] * (points[point_num - 1][0] - points[1][0])
    # for i in range(point_num): # (int i = 1 i < point_num ++i):
    for i in range(1, point_num):  # 有小伙伴发现一个bug,这里做了修改,但是没有测试,需要使用的亲请测试下,以免结果不正确。
        s += points[i][1] * (points[i - 1][0] - points[(i + 1) % point_num][0])
    return numpy.around(abs(s / 2.0), 4)


'''
计算方位角
'''


def cross_point(line1, line2):  # 计算交点函数
    x1 = line1[0]  # 取四点坐标
    y1 = line1[1]
    x2 = line1[2]
    y2 = line1[3]

    x3 = line2[0]
    y3 = line2[1]
    x4 = line2[2]
    y4 = line2[3]

    k1 = (y2 - y1) * 1.0 / (x2 - x1)  # 计算k1,由于点均为整数,需要进行浮点数转化
    b1 = y1 * 1.0 - x1 * k1 * 1.0  # 整型转浮点型是关键
    if (x4 - x3) == 0:  # L2直线斜率不存在操作
        k2 = None
        b2 = 0
    else:
        k2 = (y4 - y3) * 1.0 / (x4 - x3)  # 斜率存在操作
        b2 = y3 * 1.0 - x3 * k2 * 1.0
    if k2 == None:
        x = x3
    else:
        x = (b2 - b1) * 1.0 / (k1 - k2)
    y = k1 * x * 1.0 + b1 * 1.0
    return [x, y]


def azimuth(x1, y1, x2, y2):
    angle = 0
    dx = x2 - x1
    dy = y2 - y1
    if dx == 0 and dy > 0:  # 判断象限
        angle = 0
    if dx == 0 and dy < 0:
        angle = 180
    if dy == 0 and dx > 0:
        angle = 90
    if dy == 0 and dx < 0:
        angle = 270
    if dx > 0 and dy > 0:
        angle = math.atan(dx / dy) * 180 / math.pi
    elif dx < 0 and dy > 0:
        angle = 360 + math.atan(dx / dy) * 180 / math.pi
    elif dx < 0 and dy < 0:
        angle = 180 + math.atan(dx / dy) * 180 / math.pi
    elif dx > 0 and dy < 0:
        angle = 180 + math.atan(dx / dy) * 180 / math.pi
    angle = 90 - angle
    angle = math.radians(angle)
    return angle  # j


'''
计算西北角
'''


def distance(point, poly):
    d = {}
    min_d = []
    azimuth_2 = {}
    for Endpoint in poly:
        distance_list = math.sqrt((Endpoint[0] - point[0]) ** 2 + (Endpoint[1] - point[1]) ** 2)
        d.update({tuple(Endpoint): distance_list})
    for key, val in d.items():
        if val == min(d.values()):
            min_d.append(key)
    if len(min_d) > 1:
        for x, y in min_d:
            angle = azimuth(x, y, point[0], point[1])
            azimuth_2.update({(x, y): angle})
        min_point = max(azimuth_2, key=azimuth_2.get)
        return min_point
    elif len(min_d) == 1:
        min_point = min_d[0]
        return min_point


'''
重画西北角
'''


def Select_element():
    global acad, doc, mp, original_area
    acad = win32com.client.Dispatch("AutoCAD.Application")
    doc = acad.ActiveDocument
    doc.Utility.Prompt("\n醉后不知天在水\n满船清梦压星河\n")
    mp = doc.ModelSpace  # 模型空间
    tk.messagebox.showinfo('提示', "请在屏幕拾取图元,以Enter键结束")
    try:
        doc.SelectionSets.Item("SS1").Delete()
    except:
        tk.messagebox.showinfo('警告', "Delete selection failed")
    slt = doc.SelectionSets.Add("SS1")
    slt.SelectOnScreen()
    mmm = float(text1_var.get())

    for x in slt:
        if x.ObjectName == "AcDbPolyline":
            original_area = x.Area  # 面积
            old_coord = list_format_conversion(x.Coordinates, leixing=True)
            new_coord = tuple({}.fromkeys(old_coord).keys())  # 剔除重复点
            list4 = []
            for ier in old_coord:
                if ier not in list4:
                    list4.append(ier)
                else:
                    center, radius = vtpnt(ier[0], ier[1], 0), 2

                    cenobj = acad.ActiveDocument.Layers.Add("01重复点")
                    acad.ActiveDocument.ActiveLayer = cenobj
                    ClrNum = 2
                    cenobj.color = ClrNum
                    mp.AddCircle(center, radius)

            Polyline_coordinates = [list(x) for x in new_coord]  # 改变坐标格式【【1,2】,【4,3】,【6,7】】

            if not polyline_order(Polyline_coordinates):  # 若逆时针,反转列表
                Polyline_coordinates.reverse()

            poly_x = [x[0] for x in Polyline_coordinates]
            poly_y = [y[1] for y in Polyline_coordinates]
            max_y = max(poly_y)
            min_x = min(poly_x)

            northwest_point = [min_x, max_y]  # 矩形框西北角
            northwest_point_end_point_distance = distance(northwest_point, Polyline_coordinates)  # 图斑最靠近图框西北角的坐标
            count = Polyline_coordinates.index(list(northwest_point_end_point_distance))  # 查找在列表中的位置

            Polyline_coordinates = Polyline_coordinates[:-1]
            for _ in range(0, count):
                delete = Polyline_coordinates.pop(0)
                Polyline_coordinates.append(delete)
            XY1 = Polyline_coordinates[0]
            XY2 = Polyline_coordinates[1]
            XY3 = Polyline_coordinates[2]
            XY4 = Polyline_coordinates[3]
            angle = azimuth(XY4[0], XY4[1], XY1[0], XY1[1])  # 角度

            angle2 = azimuth(XY3[0], XY3[1], XY2[0], XY2[1])  # 角度
            angle3 = azimuth(XY4[0], XY4[1], XY3[0], XY3[1])  # 角度

            angle4 = math.radians(180) + (angle3 - angle) - math.radians(90)
            area = mmm - original_area  # 面积差值

            d1 = math.sqrt((XY3[0] - XY4[0]) ** 2 + (XY3[1] - XY4[1]) ** 2)  # 1,2 点距离

            d5 = math.sqrt((XY2[0] - XY1[0]) ** 2 + (XY2[1] - XY1[1]) ** 2)  # 1,2 点距离

            d2 = (area * 2) / (d1 + d5)  # 延长距离

            d3 = d2 / math.cos(angle4)

            xMargin1 = XY4[0] - math.cos(angle) * d3
            yMargin1 = XY4[1] - math.sin(angle) * d3

            xMargin2 = xMargin1 + math.cos(angle3) * d1
            yMargin2 = yMargin1 + math.sin(angle3) * d1
            line1 = [xMargin1, yMargin1, xMargin2, yMargin2]
            line2 = XY2 + XY3

            dSanDian = cross_point(line1, line2)
            Polyline_coordinates[3] = [xMargin1, yMargin1]
            Polyline_coordinates[2] = [dSanDian[0], dSanDian[1]]

            ff = compute_polygon_area(Polyline_coordinates) - mmm

            if ff > 0.0:
                while True:
                    d3 = d3 - 0.000001
                    xMargin3 = XY4[0] - math.cos(angle) * (d3)
                    yMargin3 = XY4[1] - math.sin(angle) * (d3)

                    xMargin4 = xMargin3 + math.cos(angle3) * d1
                    yMargin4 = yMargin3 + math.sin(angle3) * d1

                    line1 = [xMargin3, yMargin3, xMargin4, yMargin4]
                    line2 = XY2 + XY3
                    dSanDian = cross_point(line1, line2)

                    Polyline_coordinates[3] = [xMargin3, yMargin3]
                    Polyline_coordinates[2] = [dSanDian[0], dSanDian[1]]

                    sd = compute_polygon_area(Polyline_coordinates)

                    if (mmm - 0.00004) <= sd <= (mmm + 0.00004):
                        break
            elif ff < 0.0:
                while True:
                    d3 = d3 + 0.000001
                    xMargin3 = XY4[0] - math.cos(angle) * d3
                    yMargin3 = XY4[1] - math.sin(angle) * d3

                    xMargin4 = xMargin3 + math.cos(angle3) * d1
                    yMargin4 = yMargin3 + math.sin(angle3) * d1

                    line1 = [xMargin3, yMargin3, xMargin4, yMargin4]
                    line2 = XY2 + XY3
                    dSanDian = cross_point(line1, line2)

                    Polyline_coordinates[3] = [xMargin3, yMargin3]
                    Polyline_coordinates[2] = [dSanDian[0], dSanDian[1]]

                    v = compute_polygon_area(Polyline_coordinates)

                    if (mmm - 0.00004) <= v <= (mmm + 0.00004):
                        break
            else:
                pass

            Polyline_coordinates = numpy.array([m for n in Polyline_coordinates for m in n], dtype=numpy.float)

            points = vtFloat(Polyline_coordinates)
            # 设定图层
            layerobj = acad.ActiveDocument.Layers.Add("02调整后面积图层")
            acad.ActiveDocument.ActiveLayer = layerobj
            # 多段线颜色
            ClrNum = 1
            layerobj.color = ClrNum
            polylineobj = mp.AddLightweightPolyline(points)
            polylineobj.Closed = True
    messagebox.showinfo("tip","完成。")


lable1 = tk.Label(window, text="[面积替换:平方米]", width=15).grid(row=0, column=0)
text1_var = tk.StringVar()  # 获取text_1输入的值
text1_var.set(r'400')
text1 = tk.Entry(window, textvariable=text1_var, bd=5).grid(row=0, column=1)
tk.Button(window, text="开始", width=15, height=1, command=Select_element, bg="Silver").grid(row=0, column=2)
window.mainloop()

标签:angle,批量,point,0.1,list,coordinates,Polyline,权属,math
来源: https://blog.csdn.net/weixin_42479058/article/details/118256428

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有