【教學類】20250605立體紙盤(3邊形-22邊形,角度5、10……40,45)

背景需求

在《自助餐》活動中,

【教學類-53-01】20240918自助餐餐盤-CSDN博客文章瀏覽閱讀984次,點贊29次,收藏11次。【教學類-53-01】20240918自助餐餐盤 https://blog.csdn.net/reasonsummer/article/details/142340542?spm=1011.2415.3001.5331

我發現提供的紙盤是平面的,不能裝紙片(容易灑在地上、桌上),

所以最后還是用紙碗來裝、用膠水黏在平面紙盤

我想把平面紙盤變成有立體的紙盤

簡單做了一個四邊形碗。

但是我的黏貼角度是很隨機的。在已有黑色圖案的紙盤上畫畫,線條不明顯,我還是重做一個白底的模型。

我想測算黏貼多少角度,可以變出一個凹形的碗

經過deepseek求助,繪畫相應的草圖,實現我想要的效果

自制圓形,設計3邊形-22邊形的立體紙盤,其中黏貼角的角度為5度、10度、15度、20度、25度、30度、35度、40度、45度。

'''
自助餐紙盤 角度20,3-22邊形(再大就灰色部分就貼不滿了。角度10、15、20、25、30、35、40、45
手動刪除部分肯定不能黏貼的
deepseek,阿夏
20250605
'''from PIL import Image, ImageDraw, ImageFont
import math
import os
import shutil
from docx import Document
from docx.shared import Cm
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import pythoncom
from win32com.client import Dispatch
from PyPDF2 import PdfMerger# 加載黑體字體(使用系統自帶的黑體)
try:font = ImageFont.truetype("simhei.ttf", 50)  # Windows系統黑體
except:try:font = ImageFont.truetype("Arial Unicode.ttf", 50)  # Mac系統備用字體except:font = ImageFont.load_default()  # 默認字體# 各種角度旋轉10、15、20...45
for angles in range(10, 50, 5):first = 3last = 25x = list(range(first, last+1))path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250605餐盤'new = os.path.join(path, '00圖片')os.makedirs(new, exist_ok=True)for i, xx in enumerate(x):# 創建1000x1000白色畫布width, height = 1000, 1000image = Image.new('RGB', (width, height), 'white')draw = ImageDraw.Draw(image)# 畫一個1000x1000的白色填充黑色圓形,10磅粗細draw.ellipse([(0, 0), (width-1, height-1)], fill='white', outline='black', width=10)# 計算正多邊形的頂點def calculate_polygon_points(center_x, center_y, size, sides):points = []for i in range(sides):angle_deg = 360/sides * i - 30  # 旋轉30度使頂點朝上angle_rad = math.pi / 180 * angle_degx = center_x + size * math.cos(angle_rad)y = center_y + size * math.sin(angle_rad)points.append((x, y))return points# 中心點center_x, center_y = width // 2, height // 2poly_size = 300  # 多邊形大小circle_radius = 500  # 大圓半徑# 計算多邊形頂點poly_points = calculate_polygon_points(center_x, center_y, poly_size, xx)# 存儲所有交點坐標black_intersections = []gray_intersections = []# 從多邊形頂點延伸到畫布邊緣 (黑線)for point in poly_points:# 計算方向向量dx = point[0] - center_xdy = point[1] - center_y# 歸一化length = math.sqrt(dx*dx + dy*dy)dx /= lengthdy /= length# 計算延伸到邊緣的點edge_x = point[0] + dx * (circle_radius - poly_size)edge_y = point[1] + dy * (circle_radius - poly_size)black_intersections.append((edge_x, edge_y))# 畫線draw.line([(point[0], point[1]), (edge_x, edge_y)], fill='black', width=10)# 從多邊形頂點偏移指定角度延伸到畫布邊緣 (灰線)for point in poly_points:# 計算當前頂點的角度angle = math.atan2(point[1] - center_y, point[0] - center_x)# 計算偏移指定角度的方向angle_offset = angle + math.radians(angles)dx_offset = math.cos(angle_offset)dy_offset = math.sin(angle_offset)# 計算延伸到邊緣的點 - 使用直線與圓的交點公式a = dx_offset**2 + dy_offset**2b = 2*(dx_offset*(point[0]-center_x) + dy_offset*(point[1]-center_y))c = (point[0]-center_x)**2 + (point[1]-center_y)**2 - circle_radius**2discriminant = b**2 - 4*a*cif discriminant >= 0:t1 = (-b + math.sqrt(discriminant))/(2*a)t2 = (-b - math.sqrt(discriminant))/(2*a)t = max(t1, t2)  # 選擇正的、較大的t值edge_x_offset = point[0] + t*dx_offsetedge_y_offset = point[1] + t*dy_offsetelse:# 如果沒有交點,使用原來的方法作為備用edge_x_offset = point[0] + dx_offset * (circle_radius - poly_size)edge_y_offset = point[1] + dy_offset * (circle_radius - poly_size)gray_intersections.append((edge_x_offset, edge_y_offset))# 畫偏移線draw.line([(point[0], point[1]), (edge_x_offset, edge_y_offset)], fill='gray', width=10)# 繪制并填充三角形for i in range(xx):triangle_points = [poly_points[i],black_intersections[i],gray_intersections[i]]draw.polygon(triangle_points, fill='gray', outline=None)# 虛線繪制函數def draw_dashed_polygon(draw, points, fill, outline, width, dash_pattern):lines = []for i in range(len(points)):start = points[i]end = points[(i+1)%len(points)]lines.append((start, end))for start, end in lines:dx = end[0] - start[0]dy = end[1] - start[1]length = math.sqrt(dx*dx + dy*dy)dx /= lengthdy /= lengthdrawn_length = 0dash_index = 0while drawn_length < length:segment_length = dash_pattern[dash_index % len(dash_pattern)]segment_end = min(drawn_length + segment_length, length)if dash_index % 2 == 0:segment_start_x = start[0] + dx * drawn_lengthsegment_start_y = start[1] + dy * drawn_lengthsegment_end_x = start[0] + dx * segment_endsegment_end_y = start[1] + dy * segment_enddraw.line([(segment_start_x, segment_start_y), (segment_end_x, segment_end_y)], fill=outline, width=width)drawn_length = segment_enddash_index += 1# 最后畫中心多邊形,使用虛線輪廓poly_points = calculate_polygon_points(center_x, center_y, poly_size, xx)draw.polygon(poly_points, fill='white', outline=None)draw_dashed_polygon(draw, poly_points, fill=None, outline='gray', width=5, dash_pattern=[10, 10])# 在中心添加文字說明text = f"{xx}邊形 角度{angles}"text_width, text_height = draw.textsize(text, font=font)text_x = center_x - text_width // 2text_y = center_y - text_height // 2draw.text((text_x, text_y), text, fill='black', font=font)# 再畫大圓,蓋在最上面draw.ellipse([(0, 0), (width-1, height-1)], outline='black', width=10)# 保存圖像image.save(os.path.join(new, f'{i+1:02}邊形角度{angles}.png'))# print("所有圖片生成完成!")# 第二部分:處理Word文檔和PDF轉換
output_folder = os.path.join(path, '零時')
os.makedirs(output_folder, exist_ok=True)
docx_template = os.path.join(path, '立體餐盤.docx')# 獲取所有PNG圖片
png_files = [f for f in os.listdir(new) if f.lower().endswith('.png')]
print("找到的PNG文件:", png_files)# 復制10份每種圖片(通過重復列表實現)
expanded_png_files = []
for png in png_files:# expanded_png_files.extend([png] * 10)expanded_png_files.extend([png] * 1)        # 測試一份print("擴展后的圖片列表:", len(expanded_png_files))# 將圖片分成2個一組
image_pairs = [expanded_png_files[i:i+2] for i in range(0, len(expanded_png_files), 2)]
print("圖片分組數量:", len(image_pairs))# 處理Word文檔
for idx, pair in enumerate(image_pairs, start=1):try:doc = Document(docx_template)if len(doc.tables) == 0:print("文檔中沒有表格")continuetable = doc.tables[0]if len(table.rows) < 1 or len(table.rows[0].cells) < 2:print("表格格式不符合要求")continue# 清除單元格內容for i in range(2):for paragraph in table.rows[0].cells[i].paragraphs:for run in paragraph.runs:run.clear()# 插入圖片并設置大小和對齊方式for i, img_name in enumerate(pair):if i >= 2:  # 只處理前兩張圖片breakcell = table.rows[0].cells[i]img_path = os.path.join(new, img_name)# 創建段落并設置對齊方式paragraph = cell.paragraphs[0] if cell.paragraphs else cell.add_paragraph()# 00格子左對齊,01格子右對齊if i == 0:paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFTelse:paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT# 添加圖片run = paragraph.add_run()run.add_picture(img_path, width=Cm(13.5), height=Cm(13.5))output_docx = os.path.join(output_folder, f"{idx:03}.docx")doc.save(output_docx)print(f"已生成: {output_docx}")except Exception as e:print(f"處理第{idx}組時出錯:", str(e))# 轉換為PDF
try:pythoncom.CoInitialize()word = Dispatch('Word.Application')word.Visible = Falsepdf_files = []for file in sorted(os.listdir(output_folder)):if file.endswith('.docx'):docx_path = os.path.join(output_folder, file)pdf_path = os.path.join(output_folder, f"{os.path.splitext(file)[0]}.pdf")try:doc = word.Documents.Open(os.path.abspath(docx_path))doc.SaveAs(os.path.abspath(pdf_path), FileFormat=17)  # 17是PDF格式doc.Close()pdf_files.append(pdf_path)print(f"已轉換為PDF: {pdf_path}")except Exception as e:print(f"轉換{file}為PDF時出錯:", str(e))word.Quit()pythoncom.CoUninitialize()# 合并PDFif pdf_files:merger = PdfMerger()for pdf in sorted(pdf_files):try:merger.append(pdf)except Exception as e:print(f"合并{pdf}時出錯:", str(e))merged_pdf = os.path.join(path, f"餐盤合并_{first}-{last}邊形_角度{angles}.pdf")merger.write(merged_pdf)merger.close()print(f"已合并PDF: {merged_pdf}")
except Exception as e:print("PDF處理過程中出錯:", str(e))# 清理臨時文件(可選)
shutil.rmtree(output_folder)print("處理完成!")

結果:184張

手動刪除一些目測就不能用的圖片

合并代碼

'''
自助餐紙盤 角度20,3-22邊形(再大就灰色部分就貼不滿了。角度10、15、20、25、30、35、40、45
手動刪除部分肯定不能黏貼的
deepseek,阿夏
20250605
'''from PIL import Image, ImageDraw
import math
import os,time
import shutil
from docx import Document
from docx.shared import Cm
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
import pythoncom
from win32com.client import Dispatch
from PyPDF2 import PdfMergerpath = r'C:\Users\jg2yXRZ\OneDrive\桌面\20250605餐盤'
new = os.path.join(path, '00圖片')
os.makedirs(new, exist_ok=True)
# 第二部分:處理Word文檔和PDF轉換
output_folder = os.path.join(path, '零時')
os.makedirs(output_folder, exist_ok=True)
docx_template = os.path.join(path, '立體餐盤.docx')# 獲取所有PNG圖片
png_files = [f for f in os.listdir(new) if f.lower().endswith('.png')]
print("找到的PNG文件:", png_files)# 復制10份每種圖片(通過重復列表實現)
expanded_png_files = []
for png in png_files:# expanded_png_files.extend([png] * 10)expanded_png_files.extend([png] * 1)        # 測試一份print("擴展后的圖片列表:", len(expanded_png_files))# 將圖片分成2個一組
image_pairs = [expanded_png_files[i:i+2] for i in range(0, len(expanded_png_files), 2)]
print("圖片分組數量:", len(image_pairs))# 處理Word文檔
for idx, pair in enumerate(image_pairs, start=1):try:doc = Document(docx_template)if len(doc.tables) == 0:print("文檔中沒有表格")continuetable = doc.tables[0]if len(table.rows) < 1 or len(table.rows[0].cells) < 2:print("表格格式不符合要求")continue# 清除單元格內容for i in range(2):for paragraph in table.rows[0].cells[i].paragraphs:for run in paragraph.runs:run.clear()# 插入圖片并設置大小和對齊方式for i, img_name in enumerate(pair):if i >= 2:  # 只處理前兩張圖片breakcell = table.rows[0].cells[i]img_path = os.path.join(new, img_name)# 創建段落并設置對齊方式paragraph = cell.paragraphs[0] if cell.paragraphs else cell.add_paragraph()# 00格子左對齊,01格子右對齊if i == 0:paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.LEFTelse:paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT# 添加圖片run = paragraph.add_run()run.add_picture(img_path, width=Cm(13.5), height=Cm(13.5))output_docx = os.path.join(output_folder, f"{idx:03}.docx")doc.save(output_docx)print(f"已生成: {output_docx}")except Exception as e:print(f"處理第{idx}組時出錯:", str(e))# 轉換為PDF
try:pythoncom.CoInitialize()word = Dispatch('Word.Application')word.Visible = Falsepdf_files = []for file in sorted(os.listdir(output_folder)):if file.endswith('.docx'):docx_path = os.path.join(output_folder, file)pdf_path = os.path.join(output_folder, f"{os.path.splitext(file)[0]}.pdf")try:doc = word.Documents.Open(os.path.abspath(docx_path))doc.SaveAs(os.path.abspath(pdf_path), FileFormat=17)  # 17是PDF格式doc.Close()pdf_files.append(pdf_path)print(f"已轉換為PDF: {pdf_path}")except Exception as e:print(f"轉換{file}為PDF時出錯:", str(e))word.Quit()pythoncom.CoUninitialize()# 合并PDFif pdf_files:merger = PdfMerger()for pdf in sorted(pdf_files):try:merger.append(pdf)except Exception as e:print(f"合并{pdf}時出錯:", str(e))merged_pdf = os.path.join(path, f"餐盤合并.pdf")# merged_pdf = os.path.join(path, f"餐盤合并_{first}-{last}邊形_角度{angles}.pdf")merger.write(merged_pdf)time.sleep(5)merger.close()print(f"已合并PDF: {merged_pdf}")
except Exception as e:print("PDF處理過程中出錯:", str(e))# 清理臨時文件(可選)
shutil.rmtree(output_folder)print("處理完成!")

結果展示

一個有趣的旋轉圖

20250605立體紙盤圖片的旋轉效果

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/83701.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/83701.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/83701.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GC1809:高性能24bit/192kHz音頻接收芯片解析

1. 芯片概述 GC1809 是數字音頻接收芯片&#xff0c;支持IEC60958、S/PDIF、AES3等協議&#xff0c;集成8選1輸入切換、低抖動時鐘恢復和24bit DAC&#xff0c;適用于家庭影院、汽車音響等高保真場景。 核心特性 高精度&#xff1a;24bit分辨率&#xff0c;動態范圍105dB&…

Next.js 中間件鑒權繞過漏洞 CVE-2025-29927

前言:CVE-2025-29927 是一個影響 Next.js 的嚴重漏洞&#xff0c;源于開發者信任了客戶端請求中攜帶的 X-Middleware-Rewrite 頭部字段。攻擊者可以手動構造該頭部&#xff0c;實現繞過中間件邏輯&#xff0c;訪問本應受保護的資源或 API。 影響版本&#xff1a;Next.js < …

第1章 數據分析簡介

第1章 數據分析簡介 1.1 數據分析 當今世界對信息技術依賴日深,每天產生和存儲海量數據,來源于自動檢測系統、傳感器、科學儀器,以及銀行取錢、買東西、寫博客、發微博等日常行為。 數據與信息在形式上不同:數據是無形式可言的字節流,難理解其本質;信息是對數據集處理后…

邊緣計算網關賦能沸石轉輪運行故障智能診斷的配置實例

一、項目背景 在環保行業&#xff0c;隨著國家對大氣污染治理要求的不斷提高&#xff0c;VOCs廢氣處理成為了眾多企業的重要任務。沸石轉輪作為一種高效的VOCs治理設備&#xff0c;被廣泛應用于石油化工、汽車制造、印刷包裝等主流行業。這些行業生產規模大、廢氣排放量多&…

20250602在Ubuntu20.04.6下修改壓縮包的日期和時間

rootrootrootroot-X99-Turbo:~$ ll -rwxrwxrwx 1 rootroot rootroot 36247187308 5月 23 10:23 Android13.0地面站.tgz* rootrootrootroot-X99-Turbo:~$ touch 1Android13.0地面站.tgz rootrootrootroot-X99-Turbo:~$ ll -rwxrwxrwx 1 rootroot rootroot 36247187308 6月…

windows無法安裝到這個磁盤,選中的磁盤采用gpt分區儀式

解決辦法&#xff1a; 我才用的是一個網友分享的微軟官方解決辦法&#xff0c;成功了&#xff0c;但是不知道會不會i有什么影響。將所有分區刪掉&#xff0c;這時磁盤變成為分配的空間。我個人是兩塊固態&#xff0c;一塊m.2&#xff0c;一塊sata&#xff1b;所以我直接將500g…

使用Composer創建公共類庫

概述 如果多個項目中存在使用相同類庫、模塊的情況&#xff0c;此時可以考慮將類庫或者模塊單獨抽取出來&#xff0c;形成獨立類庫&#xff0c;通過composer 來進行依賴管理&#xff0c;這樣可以更方便維護&#xff0c;大大提升開發效率。 優勢 可以對特定模塊進行統一維護和…

Ubuntu中TFTP服務器安裝使用

TFTP服務器 在 Ubuntu 下使用 TFTP&#xff08;Trivial File Transfer Protocol&#xff09; 服務&#xff0c;通常用于簡單的文件傳輸&#xff08;如網絡設備固件更新、嵌入式開發等&#xff09;。 1 TFTP服務器安裝 sudo apt-get install tftp-hpa sudo apt-get install…

前端面試總結

1.請做下自我介紹 技術棧 工作經歷 2.挑一個項目詳細講一下 介紹了一個項目的業務&#xff0c;重點講了一個動態表單的實現&#xff0c;從業務、擴展性、可維護性、性能提升 3.場景題&#xff1a;問答怎么做&#xff0c;表單之間關聯&#xff0c;回答不同問題跳轉到不同的下一個…

Python訓練打卡Day38

Dataset和Dataloader類 知識點回顧&#xff1a; Dataset類的__getitem__和__len__方法&#xff08;本質是python的特殊方法&#xff09;Dataloader類minist手寫數據集的了解 在遇到大規模數據集時&#xff0c;顯存常常無法一次性存儲所有數據&#xff0c;所以需要使用分批訓練的…

web3-區塊鏈基礎:從區塊添加機制到哈希加密與默克爾樹結構

區塊鏈基礎&#xff1a;從區塊添加機制到哈希加密與默克爾樹結構 什么是區塊鏈 抽象的回答: 區塊鏈提供了一種讓多個參與方在沒有一個唯一可信方的情況下達成合作 若有可信第三方 > 不需要區塊鏈 [金融系統中常常沒有可信的參與方] 像股票市場&#xff0c;或者一個國家的…

MySQL 索引:為使用 B+樹作為索引數據結構,而非 B樹、哈希表或二叉樹?

在數據庫的世界里&#xff0c;性能是永恒的追求。而索引&#xff0c;作為提升查詢速度的利器&#xff0c;其底層數據結構的選擇至關重要。如果你深入了解過 MySQL&#xff08;尤其是其主流存儲引擎 InnoDB&#xff09;&#xff0c;你會發現它不約而同地選擇了 B樹 作為索引的主…

Kafka broker 寫消息的過程

Producer → Kafka Broker → Replication → Consumer|Partition chosen (by key or round-robin)|Message appended to end of log (commit log)上面的流程是kafka 寫操作的大體流程。 kafka 不會特意保留message 在內存中&#xff0c;而是直接寫入了disk。 那么消費的時候&…

leetcode hot100(兩數之和、字母異位詞分組、最長連續序列)

兩數之和 題目鏈接 參考鏈接&#xff1a; 題目描述&#xff1a; 暴力法 雙重循環查找目標值 class Solution {public int[] twoSum(int[] nums, int target) {int[] res new int[2];for(int i 0 ; i < nums.length ; i){boolean isFind false;for(int j i 1 ; j …

SkyWalking架構深度解析:分布式系統監控的利器

一、SkyWalking概述 SkyWalking是一款開源的APM(應用性能監控)系統&#xff0c;專門為微服務、云原生和容器化架構設計。它由Apache軟件基金會孵化并畢業&#xff0c;已成為分布式系統監控領域的明星項目。 核心特性 ?分布式追蹤?&#xff1a;跨服務調用鏈路的完整追蹤?服務…

Matlab程序設計基礎

matlab程序設計基礎 程序設計函數文件1.函數文件的基本結構2.創建并使用函數文件的示例3.帶多個輸出的函數示例4.包含子函數的函數文件 流程控制1. if 條件語句2. switch 多分支選擇語句3. try-catch 異常處理語句ME與lasterr 4. while 循環語句5. for 循環語句break和continue…

Client-Side Path Traversal 漏洞學習筆記

近年來,隨著Web前端技術的飛速發展,越來越多的數據請求和處理邏輯被轉移到客戶端(瀏覽器)執行。這大大提升了用戶體驗,但也帶來了新的安全威脅。其中,Client-Side Path Traversal(客戶端路徑穿越,CSPT)作為一種新興的漏洞類型,逐漸受到安全研究者和攻擊者的關注。本文…

基于Socketserver+ThreadPoolExecutor+Thread構造的TCP網絡實時通信程序

目錄 介紹&#xff1a; 源代碼&#xff1a; Socketserver-服務端代碼 Socketserver客戶端代碼&#xff1a; 介紹&#xff1a; socketserver是一種傳統的傳輸層網絡編程接口&#xff0c;相比WebSocket這種應用層的協議來說&#xff0c;socketserver比較底層&#xff0c;soc…

【無標題】平面圖四色問題P類歸屬的嚴格論證——基于拓撲收縮與動態調色算法框架

平面圖四色問題P類歸屬的嚴格論證——基于拓撲收縮與動態調色算法框架 --- #### **核心定理** 任意平面圖 \(G (V, E)\) 的四色著色問題可在多項式時間 \(O(|V|^2)\) 內求解&#xff0c;且算法正確性由以下三重保證&#xff1a; 1. **拓撲不變性**&#xff08;Kuratowsk…

HALCON 深度學習訓練 3D 圖像的幾種方式優缺點

HALCON 深度學習訓練 3D 圖像的幾種方式優缺點 ** 在計算機視覺和工業檢測等領域&#xff0c;3D 圖像數據的處理和分析變得越來越重要&#xff0c;HALCON 作為一款強大的機器視覺軟件&#xff0c;提供了多種深度學習訓練 3D 圖像的方式。每種方式都有其獨特的設計思路和應用場…