Как я могу потянуть кривую Безье с помощью PIL Python?

Прежде всего, я хотел бы рассмотреть объявление только одной структуры, поскольку поля в A, B и C одинаковы. Например:

type FooBar struct {
    TransactionDate  string 
    TotalAmount      string 
    TotalTransaction string 
}

Затем для вашей функции вы можете попробовать переписать его следующим образом:

func compareReplace(a []FooBar, b []FooBar) []FooBar{
 var c []foobar
 for i := 0; i < len(a); i++ { 
  if a[i].TransactionDate == b[i].TransactionDate {
        if b[i].TotalTransaction != "0" {
            c = append(c, b[i])
        }
  }
 }
 return c
}

Затем, наконец, вы можете исправить свою логику:

[112 ]
13
задан carrier 29 October 2008 в 11:59
поделиться

3 ответа

Кривая Безье не то, что трудно привлечь себя. Учитывая три точки A, B, C Вы требуете трех линейных интерполяций для рисования кривой. Мы используем скаляр t в качестве параметра для линейной интерполяции:

P0 = A * t + (1 - t) * B
P1 = B * t + (1 - t) * C

Это интерполирует между двумя краями, которые мы создали, край AB и край до н.э. Единственная вещь, которую мы теперь должны сделать для вычисления точки, которую мы должны потянуть, интерполируют между P0 и P1 с помощью того же t как так:

Pfinal = P0 * t + (1 - t) * P1

существует несколько вещей, которые должны быть сделаны, прежде чем мы на самом деле потянем кривую. Прежде всего мы имеем, обойдет приблизительно dt (дельта t), и мы должны знать это 0 <= t <= 1. Когда Вы смогли воображать, это не даст нам плавную кривую, вместо этого она приводит только к дискретному набору положений, в которых можно вывестись на печать. Самый легкий способ решить это состоит в том, чтобы просто чертить линию между текущей точкой и предыдущей точкой.

12
ответ дан 1 December 2019 в 17:51
поделиться

Можно использовать aggdraw сверху PIL, кривые Безье , поддерживал .

РЕДАКТИРОВАНИЕ:

я сделал пример только, чтобы обнаружить, что существует ошибка в Path, класс относительно curveto :(

Вот пример так или иначе:

from PIL import Image
import aggdraw

img = Image.new("RGB", (200, 200), "white")
canvas = aggdraw.Draw(img)

pen = aggdraw.Pen("black")
path = aggdraw.Path()
path.moveto(0, 0)
path.curveto(0, 60, 40, 100, 100, 100)
canvas.path(path.coords(), path, pen)
canvas.flush()

img.save("curve.png", "PNG")
img.show()

Это должно исправить ошибку, если Вы подлежите перекомпиляции модуля...

8
ответ дан 1 December 2019 в 17:51
поделиться
def make_bezier(xys):
    # xys should be a sequence of 2-tuples (Bezier control points)
    n = len(xys)
    combinations = pascal_row(n-1)
    def bezier(ts):
        # This uses the generalized formula for bezier curves
        # http://en.wikipedia.org/wiki/B%C3%A9zier_curve#Generalization
        result = []
        for t in ts:
            tpowers = (t**i for i in range(n))
            upowers = reversed([(1-t)**i for i in range(n)])
            coefs = [c*a*b for c, a, b in zip(combinations, tpowers, upowers)]
            result.append(
                tuple(sum([coef*p for coef, p in zip(coefs, ps)]) for ps in zip(*xys)))
        return result
    return bezier

def pascal_row(n, memo={}):
    # This returns the nth row of Pascal's Triangle
    if n in memo:
        return memo[n]
    result = [1]
    x, numerator = 1, n
    for denominator in range(1, n//2+1):
        # print(numerator,denominator,x)
        x *= numerator
        x /= denominator
        result.append(x)
        numerator -= 1
    if n&1 == 0:
        # n is even
        result.extend(reversed(result[:-1]))
    else:
        result.extend(reversed(result))
    memo[n] = result
    return result

Это, например, рисует сердечко:

from PIL import Image
from PIL import ImageDraw

if __name__ == '__main__':
    im = Image.new('RGBA', (100, 100), (0, 0, 0, 0)) 
    draw = ImageDraw.Draw(im)
    ts = [t/100.0 for t in range(101)]

    xys = [(50, 100), (80, 80), (100, 50)]
    bezier = make_bezier(xys)
    points = bezier(ts)

    xys = [(100, 50), (100, 0), (50, 0), (50, 35)]
    bezier = make_bezier(xys)
    points.extend(bezier(ts))

    xys = [(50, 35), (50, 0), (0, 0), (0, 50)]
    bezier = make_bezier(xys)
    points.extend(bezier(ts))

    xys = [(0, 50), (20, 80), (50, 100)]
    bezier = make_bezier(xys)
    points.extend(bezier(ts))

    draw.polygon(points, fill = 'red')
    im.save('out.png')
21
ответ дан 1 December 2019 в 17:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: