Как создать изображение треугольника со сторонами и углами

avatar
Tejasisamazing
9 августа 2021 в 02:25
271
2
0

Как сказано в вопросе, как мне создать файл изображения треугольника, в котором вводятся стороны и углы.

В настоящее время я использую библиотеку черепах

forward(s1)
left(180-c)
forward(s2)
left(180-a)
forward(s3)
ts = turtle.getcanvas()
ts.postscript(file="file.ps")

Теперь это работает, но изображение выводится в файл ps. Поскольку я хочу, чтобы это было в форме изображения (например, изображение png/jpg/pil), мне нужно преобразовать его в него. Итак, я обнаружил, что для этого вы можете использовать

img = Image.open("file.ps")
img.save("file.png")

Но это говорит о том, что "невозможно найти Ghostscript в путях" Но поскольку я не могу установить ghostscript (по причинам) на свое устройство, я не могу преобразовать его в форму изображения. Итак, мой вопрос: есть ли какая-либо библиотека или какой-либо способ создать файл изображения треугольника, используя только стороны и углы. Не знаю, как я мог бы сделать это в PIL, так как мне нужны координаты для вершин, и я понятия не имею, как получить координаты вершин. Еще одна проблема с Turtle заключается в том, что он создает новое окно для создания изображения. Поэтому желательно, чтобы создание изображения происходило в фоновом режиме. Есть ли способ сделать это?

Изменить: код, который я сейчас использую для создания файла:

def trianglesss(s1,s2,s3):
    a = s1
    b = s2
    c = s3
    a1 = round(math.degrees(math.acos(((b**2)+(c**2)-(a**2))/(2*b*c))))
    b1 = round(math.degrees(math.acos(((c**2)+(a**2)-(b**2))/(2*a*c))))
    c1 = round(math.degrees(math.acos(((b**2)+(a**2)-(c**2))/(2*a*b))))
    turtle.tracer(0,0)
    turtle.pendown()
    turtle.speed('fastest')
    hideturtle()
    forward(s1)
    left(180-c1)
    forward(s2)
    left(180-a1)
    forward(s3)
    turtle.update()
    ts = turtle.getcanvas()
    ts.postscript(file="file.eps")
    bye()
    trisssimg = Image.open("file.eps")
    trisssimg.save("Trisss.jpg")
trianglesss(20,20,20)
#Calculating angles using the formula from:
#https://www.mathsisfun.com/algebra/trig-solving-sss-triangles.html
Источник
martineau
9 августа 2021 в 02:55
0

Пожалуйста, предоставьте более полный код графического рисунка черепахи.

martineau
9 августа 2021 в 03:21
0

Хорошо, это достаточно близко.

Ответы (2)

avatar
Jason Yang
9 августа 2021 в 06:51
1

Вы можете использовать Image и ImageDraw для рисования линии на изображении. Здесь следуйте части концепции черепахи, чтобы дать команду рисовать линии.

from math import cos, sin, pi, ceil
from PIL import Image, ImageDraw

def draw(commands, filename=None, size=None, show=True):

    x0, y0 = 0, 0
    direction = 0
    line_width, line_color = 1, 'black'
    pen_down = False
    points = []

    for command, value in commands:
        cmd = command.strip().lower()
        if cmd == "color":
            line_color = value
        elif cmd == "width":
            line_width = value
        elif cmd in ("forward", "fd", "backward", "bk"):
            distance = value
            radian = direction/180*pi if cmd in ("forward", "fd") else (direction+180)/180*pi
            x1, y1 = x0 + distance * cos(radian), y0 + distance * sin(radian)
            if pen_down:
                points.append([(x0, y0), (x1, y1), line_color, line_width])
            x0, y0 = x1, y1
        elif cmd == "left":
            direction -= value
        elif cmd == "right":
            direction += value
        elif cmd in ("penup", "pu"):
            pen_down = False
        elif cmd in ("pendown", "pd"):
            pen_down = True

    xs, ys = [], []
    for point1, point2, color, width in points:
        xs += [point1[0], point2[0]]
        ys += [point1[1], point2[1]]
    x_min, x_max, y_min, y_max = min(xs), max(xs), min(ys), max(ys)
    w, h = ceil(x_max - x_min + 1), ceil(y_max - y_min + 1)

    width, height = size if size else (w, h)
    dx, dy = (width - w)/2 - x_min, (height - h)/2 - y_min
    im = Image.new(mode="RGBA", size=(width, height), color=(0, 0, 0, 0))
    draw = ImageDraw.Draw(im, mode="RGBA")

    for point1, point2, line_color, line_width in points:
        p1, p2 = (point1[0]+dx, point1[1]+dy), (point2[0]+dx, point2[1]+dy)
        draw.line([p1, p2], fill=line_color, width=line_width)
    if filename:
        im.save(filename)
    if show:
        im.show()

commands = [("PenDown", None), ("Width", 5), ("Color", "blue"),
    ("FD", 100), ("Left", 120), ("FD", 100), ("left", 120), ("FD", 100)]

draw(commands, "Triangle.png", (200, 200))

enter image description here

avatar
martineau
9 августа 2021 в 04:41
1

Поскольку модуль turtle основан на tkinter, вы можете сделать это с помощью PIL следующим образом.

import math
from PIL import ImageGrab
import tkinter as tk
import tkinter.messagebox as tkMessageBox
from tkinter.constants import *
import turtle

WIDTH, HEIGHT = 500, 400
IMG_FILENAME = 'turtlescreen.png'  # Extension determines file format.

def trianglesss(t, s1, s2, s3):
    a = s1
    b = s2
    c = s3
    a1 = round(math.degrees(math.acos(((b**2)+(c**2)-(a**2)) / (2*b*c))))
    b1 = round(math.degrees(math.acos(((c**2)+(a**2)-(b**2)) / (2*a*c))))
    c1 = round(math.degrees(math.acos(((b**2)+(a**2)-(c**2)) / (2*a*b))))
    t.pendown()
    t.forward(s1)
    t.left(180-c1)
    t.forward(s2)
    t.left(180-a1)
    t.forward(s3)

def draw_stuff(canvas):
    screen = turtle.TurtleScreen(canvas)
    t = turtle.RawTurtle(screen.getcanvas())
    t.speed(0)  # Fastest.
    t.pencolor('black')
    t.hideturtle()
    trianglesss(t, 200, 200, 200)

def image_grab(root, widget):
    x = root.winfo_rootx() + widget.winfo_x()
    y = root.winfo_rooty() + widget.winfo_y()
    x1 = x + widget.winfo_width()
    y1 = y + widget.winfo_height()
    return ImageGrab.grab().crop((x, y, x1, y1))

def save_file(root, canvas, filename):
    """ Convert the Canvas widget into an image file. """
    # Get image of Canvas and save it to a file.
    img = image_grab(root, canvas)
    img.save(IMG_FILENAME)  # Save image file.

    tkMessageBox.showinfo("Info", "Image saved as %r" % filename, parent=root)


# Main
root = tk.Tk()
canvas = tk.Canvas(root, width=WIDTH, height=HEIGHT,
                   borderwidth=0, highlightthickness=0)
canvas.pack()

btn_frame = tk.Frame(root)
btn_frame.pack()
btn1 = tk.Button(btn_frame, text='Draw', command=lambda: draw_stuff(canvas))
btn1.pack(side=LEFT)
btn2 = tk.Button(btn_frame, text='Save',
                 command=lambda: save_file(root, canvas, IMG_FILENAME))
btn2.pack(side=LEFT)
btn3 = tk.Button(btn_frame, text='Quit', command=root.quit)
btn3.pack(side=LEFT)

root.mainloop()

Скриншот его работы:

screenshot

Tejasisamazing
9 августа 2021 в 05:02
0

Спасибо, это работает. Также я убрал кнопки для рисования и сохранения и просто вызываю функции рисования и сохранения в основном, так как хочу, чтобы это было автоматизировано. Можете ли вы сказать, как сделать команду quit после рисования и сохранения? Поскольку кнопка работает, но я хочу, чтобы она автоматически закрывалась после рисования и сохранения. Еще раз, спасибо за помощь.

Tejasisamazing
9 августа 2021 в 05:17
0

Кроме того, возможно ли выполнить работу по сохранению и созданию треугольника на заднем плане? Спасибо

martineau
9 августа 2021 в 08:01
0

Вы можете позвонить root.quit(), чтобы завершить mainloop(). Я не думаю, что вы можете создать треугольник на заднем плане, хотя я не совсем уверен, что вы имеете в виду. Для этого нужно сделать скриншот рисунка, сделанного turtle, поэтому экран должен быть виден.