当前位置: 首页 > article >正文

luceda ipkiss教程 43:画渐变圆弧型波导

案例分享:
在这里插入图片描述

from si_fab import all as pdk
import ipkiss3.all as i3
from ipcore.properties.restrictions import RestrictTuple
from ipkiss.geometry.shapes.modifiers import __ShapePathBase__
import numpy as np
from math import atan2

class ShapePathTaperExtended(__ShapePathBase__):
    """ Tapered path with extended ends based on a shape. """
    extension = i3.Tuple2Property(
        restriction=RestrictTuple((float)),
        doc="extension of the path shape at start and end: (start, end)"
    )
    end_path_width = i3.PositiveNumberProperty(doc="end width of path")
    start_path_width = i3.PositiveNumberProperty(doc="start width of path")

    def _default_end_path_width(self):
        return self.path_width

    def _default_path_width(self):
        return self.start_path_width

    def _default_extension(self):
        return 0., 0.

    def __init__(self, original_shape, start_path_width, end_path_width, **kwargs):
        super(ShapePathTaperExtended, self).__init__(
            original_shape=original_shape,
            start_path_width=start_path_width,
            end_path_width=end_path_width,
            **kwargs)

    def define_points(self, pts):
        # TODO: include start_face_angle and end_face_angle in the calculations
        start_ext, end_ext = self.extension
        west_coords = i3.Shape()
        east_coords = i3.Shape()
        orig_shp = i3.Shape(self.__get_original_shape_without_straight_angles__())
        start_angle, end_angle = orig_shp.get_face_angles()
        if len(orig_shp) == 0 or np.isclose(orig_shp.length(), 0.):
            return pts
        # begin
        orig_shp[0] = orig_shp[0].move_polar(-start_ext, start_angle)
        # end
        orig_shp[-1] = orig_shp[-1].move_polar(end_ext, end_angle)
        dist = [i3.distance(orig_shp[_], orig_shp[_ + 1]) for _ in range(len(orig_shp) - 1)]
        widths = [(self.end_path_width - self.path_width) * np.sum(dist[:_]) / np.sum(dist) + self.path_width for _ in
                  range(len(orig_shp))]
        coords = orig_shp.points
        n_points = len(coords)
        start_angle, end_angle = orig_shp.get_face_angles()
        # middle
        for i in range(n_points):
            x = coords[i][0]
            y = coords[i][1]
            if i == 0:
                angle1 = i3.DEG2RAD * start_angle
                angle2 = atan2(coords[i + 1][1] - y, coords[i + 1][0] - x)
            elif i == n_points - 1:
                angle1 = atan2(y - coords[i - 1][1], x - coords[i - 1][0])
                angle2 = i3.DEG2RAD * end_angle
            else:
                angle1 = atan2(y - coords[i - 1][1], x - coords[i - 1][0])
                angle2 = atan2(coords[i + 1][1] - y, coords[i + 1][0] - x)
            angle = angle1 + 0.5 * (angle2 - angle1 + np.pi) % (np.pi) - 0.5 * np.pi
            turn = (angle2 - angle1) % (2 * np.pi)
            ca = np.cos(angle)
            sa = np.sin(angle)
            if turn == np.pi and i not in [0, n_points - 1]:
                i3.LOG.error("Path to Boundary conversion is not possible with paths that turn 180 degree at a node")
                raise SystemExit
            w = 0.5 * widths[i] / np.abs(np.cos(0.5 * turn))
            c_west = (x - w * sa, y + w * ca)
            c_east = (x + w * sa, y - w * ca)
            west_coords.append(c_west)
            east_coords.append(c_east)
        east_coords.reverse()
        pts.extend(west_coords)
        pts.extend(east_coords)
        pts.append(west_coords[0])
        return pts


class gradient_arc(i3.PCell):
    class Layout(i3.LayoutView):
        radius = i3.PositiveNumberProperty(doc="Radius of the central bends", default=100.0)
        def _generate_elements(self, elems):
            shape_wg1 = [
                (0.0, 0.0),
                (self.radius, 0),
                (self.radius, self.radius),
                (self.radius, 2 * self.radius),
                (0, 2 * self.radius),
            ]
            shape_wg1_path = i3.ShapeRound(original_shape=shape_wg1, radius=self.radius)
            elems += i3.Boundary(layer=i3.TECH.PPLAYER.SI,
                                 shape=ShapePathTaperExtended(
                                     original_shape=shape_wg1_path,
                                     start_path_width=10,
                                     end_path_width=1,
                                 ))
            return elems


if __name__ == '__main__':
    gradient_arc().Layout().visualize()



http://www.kler.cn/a/163100.html

相关文章:

  • 在C++上实现反射用法
  • 卸载一直显示在运行的应用
  • C++笔记---异常
  • 【智谱开放平台-注册/登录安全分析报告】
  • 【安全测试】sqlmap工具(sql注入)学习
  • 三周精通FastAPI:40 部署应用程序或任何类型的 Web API 概念
  • ModuleNotFoundError: No module named ‘dlib‘
  • C_15练习题
  • Qt与Sqlite3
  • 车联网软件定义汽车安全攻击示例
  • 第15章:随堂复习与企业真题(File类与IO流)
  • PaddleClas学习3——使用PPLCNet模型对车辆朝向进行识别(c++)
  • 希尔排序详解:一种高效的排序方法
  • go语言 grpc 拦截器
  • 前端使用视频作为背景图的方法
  • 深入了解 Axios 拦截器
  • log4j(日志的配置)
  • C语言WFC实现绘制贝塞尔曲线的函数
  • 【交流】PHP生成唯一邀请码
  • 安装node.js并创建第一个vue项目
  • 【EI会议征稿中】2024年第四届人工智能、自动化与高性能计算国际会议(AIAHPC 2024)
  • Navicat 技术指引 | 适用于 GaussDB 分布式的数据迁移工具
  • 华为配置Smart Link主备备份示例
  • vue3递归组件---树形组件
  • 【数据仓库-10】-- 数据仓库、数据湖和湖仓一体对比
  • 剑指 Offer(第2版)面试题 21:调整数组顺序使奇数位于偶数前面