用开罗绘制贝塞尔曲线

问题描述

我需要借助 C ++ 中的 Cairo 绘制一组Bezier路径。 到目前为止,我只能画一条路。

但是我需要绘制许多由多个贝塞尔曲线和线组成的路径。

我从python生成的外部字典加载路径集合。 在这里,对于这个最小的示例,我通过变量path0引入了一条路径。

它是一个向量,由2个子向量组成。第一个代表贝塞尔曲线样条曲线,第二个代表简单的直线。

一个子向量自然有4个分量,而第二个只有2个。

这是我的代码示例。

#include <iostream>
#include <vector>
#include "cairo.h"
#include <string> 

int main(int argc,char* argv[])
{
    cairo_surface_t* surface;
    cairo_t* cr;

    surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,1000,1000);
    cr = cairo_create(surface);
    cairo_scale(cr,1,1);
    cairo_set_line_width(cr,1);
    cairo_set_source_rgb(cr,0);  

    // Here goes the svg-path. It is a bezier curve and unconnected line. 
    
    std::vector<std::vector<std::vector<double>>> path0 = { {{82.801,-204.48},{66.241,{52.561,-214.56},-235.44}},{{277.921,-192.24},{277.921,-173.5}} };
        
        // Here I put the initial point in the middle of the canvas. 

        double x0 = 300+path0[0][0][0];
        double y0 = 700+ path0[0][0][1];

        cairo_move_to(cr,x0,y0);

        // Parsing path
        for (int i = 0; i < path0.size(); i++) {
            if (path0[i].size() == 4) {
                cairo_rel_curve_to(cr,path0[i][1][0],path0[i][1][1],path0[i][2][0],path0[i][2][1],path0[i][3][0],path0[i][3][1]);
                cairo_stroke(cr);
            }
            if (path0[i].size() == 2) {
                cairo_rel_line_to(cr,symbol[0][i][1][0],symbol[0][i][1][1]);
                cairo_stroke(cr);
            }
        }
        cairo_surface_write_to_png(surface,"stroke.png");
        cairo_destroy(cr);
        cairo_surface_destroy(surface);

        return 0;

}

问题是我在画布上只看到一条曲线。第二个可能在外面。 您能帮我了解我在做什么错吗?

雅罗斯拉夫。

解决方法

您能否阐明您期望看到的内容?经过以下更改,我得到了类似两行的内容,但是我不确定这是您想要看到的内容。


System.IO.MemoryStream ms = new System.IO.MemoryStream();
System.IO.StreamWriter writer = new System.IO.StreamWriter(ms);
writer.Write(htmlDocument.Text);
writer.Flush();
writer.Dispose();
MessageAttachmentsCollectionPage attachments = new MessageAttachmentsCollectionPage();
attachments.Add(new FileAttachment
{
ODataType = "#microsoft.graph.fileAttachment",ContentBytes = ms.ToArray(),ContentType = "text/html",ContentId = "testing",Name = "My_Report.html"
});
var message = new Message
{
Subject = "My Report",Body = new ItemBody
{
ContentType = BodyType.Text,Content = "Here is your updated report from list"
},ToRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "{End User to receive report}"
}
}
},CcRecipients = new List<Recipient>()
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = "{my admin email account}"
}
}
},From = new Recipient { 
EmailAddress = new EmailAddress
{ 
Address = "{my admin email account}"
}
},Attachments = attachments
};
var graphServiceClient = GetGraphServiceClient();
await graphServiceClient.Me
.SendMail(message,null)
.Request()
.PostAsync();

结果是: enter image description here

上述程序中发生的是:

  • 首先,您致电System.IO.MemoryStream ms = new System.IO.MemoryStream(); System.IO.StreamWriter writer = new System.IO.StreamWriter(ms); writer.Write(htmlDocument.Text); writer.Flush(); writer.Dispose(); MessageAttachmentsCollectionPage attachments = new MessageAttachmentsCollectionPage(); attachments.Add(new FileAttachment { ODataType = "#microsoft.graph.fileAttachment",null) .Request() .PostAsync(); 。这决定了以下曲线的起点。
  • 然后将调用--- t.cpp.orig 2020-10-13 17:00:12.404871474 +0200 +++ t.cpp 2020-10-13 17:04:20.573101739 +0200 @@ -29,13 +29,12 @@ int main(int argc,char* argv[]) for (int i = 0; i < path0.size(); i++) { if (path0[i].size() == 4) { cairo_rel_curve_to(cr,path0[i][1][0],path0[i][1][1],path0[i][2][0],path0[i][2][1],path0[i][3][0],path0[i][3][1]); - cairo_stroke(cr); } if (path0[i].size() == 2) { - cairo_rel_line_to(cr,symbol[0][i][1][0],symbol[0][i][1][1]); - cairo_stroke(cr); + cairo_rel_line_to(cr,path0[i][1][1]); } } + cairo_stroke(cr); cairo_surface_write_to_png(surface,"stroke.png"); cairo_destroy(cr); cairo_surface_destroy(surface); 。这会将一条从当前点到cairo_move_to(cr,382.8,495.5)之类的曲线添加。另外两点描述了曲线如何弯曲。
  • 接下来,有一个呼叫cairo_rel_curve_to()
    • 在我的版本中,这将从曲线的末端开始添加线段。
    • 在您的版本中,对382.8+52.5,495.5-235.4的调用删除了该路径。由于没有当前点,因此line_to不会做任何事情(嗯,它为后续的绘制命令设置了当前点)。