Přizpůsobení tvarů v prezentaci v C++

Přehled

Tento článek popisuje, jak přizpůsobit tvary v prezentacích v Aspose.Slides úpravou geometrie tvaru pomocí editačních bodů a geometrických cest. Ukazuje, jak pracovat s GeometryPath a IGeometryPath pro úpravu existujících tvarů, provádění základních operací úpravy cesty, přidávání nebo odstraňování bodů a aplikaci aktualizované geometrie zpět na tvar.

Změna tvaru pomocí editačních bodů

Zvažte čtverec. V PowerPointu můžete pomocí edit points:

  • posunout roh čtverce dovnitř nebo ven
  • zadat zakřivení pro roh nebo bod
  • přidat nové body do čtverce
  • manipulovat body na čtverci atd.

V podstatě můžete provádět popsané úkoly na jakémkoli tvaru. Pomocí editačních bodů můžete změnit tvar nebo vytvořit nový tvar ze stávajícího.

Tipy pro úpravu tvarů

overview_image

Předtím, než začnete upravovat tvary v PowerPointu pomocí editačních bodů, můžete zvážit následující body o tvarech:

  • Tvar (nebo jeho cesta) může být buď uzavřený, nebo otevřený.
  • Když je tvar uzavřený, postrádá počáteční nebo koncový bod. Když je tvar otevřený, má začátek a konec.
  • Všechny tvary se skládají alespoň ze 2 kotevních bodů spojených čarami
  • Čára může být buď přímá, nebo zakřivená. Kotevní body určují charakter čáry.
  • Kotevní body se vyskytují jako rohové body, přímé body nebo hladké body:
    • Rohový bod je bod, kde se dvě přímé čáry setkávají pod úhlem.
    • Hladký bod je bod, kde dvě rukojeti leží na přímé linii a úseky čáry se spojují plynulou křivkou. V tomto případě jsou všechny rukojeti od kotevního bodu vzdáleny stejnou vzdáleností.
    • Přímý bod je bod, kde dvě rukojeti leží na přímé linii a úseky čáry se spojují plynulou křivkou. V tomto případě rukojeti nemusí být od kotevního bodu vzdáleny stejně.
  • Přesunutím nebo úpravou kotevních bodů (což mění úhel čar) můžete změnit vzhled tvaru.

Pro úpravu tvarů v PowerPointu pomocí editačních bodů Aspose.Slides poskytuje třídu GeometryPath a rozhraní IGeometryPath.

Jednoduché operace úpravy

Tento C++ kód vám ukazuje jak

Přidat čáru na konec cesty

void LineTo(PointF point);
void LineTo(float x, float y);

Přidat čáru na určenou pozici v cestě:

void LineTo(PointF point, uint32_t index);
void LineTo(float x, float y, uint32_t index);

Přidat kubickou Bézierovu křivku na konec cesty:

void CubicBezierTo(PointF point1, PointF point2, PointF point3);
void CubicBezierTo(float x1, float y1, float x2, float y2, float x3, float y3);

Přidat kubickou Bézierovu křivku na určenou pozici v cestě:

void CubicBezierTo(PointF point1, PointF point2, PointF point3, uint32_t index);
void CubicBezierTo(float x1, float y1, float x2, float y2, float x3, float y3, uint32_t index);

Přidat kvadratickou Bézierovu křivku na konec cesty:

void QuadraticBezierTo(PointF point1, PointF point2);
void QuadraticBezierTo(float x1, float y1, float x2, float y2);

Přidat kvadratickou Bézierovu křivku na určenou pozici v cestě:

void QuadraticBezierTo(PointF point1, PointF point2, uint32_t index);
void QuadraticBezierTo(float x1, float y1, float x2, float y2, uint32_t index);

Připojit daný oblouk k cestě:

void ArcTo(float width, float heigth, float startAngle, float sweepAngle);

Uzavřít aktuální figurku cesty:

void CloseFigure();

Nastavit pozici pro další bod:

void MoveTo(PointF point);
void MoveTo(float x, float y);

Odstranit segment cesty na zadaném indexu:

void RemoveAt(int32_t index);

Přidání vlastních bodů do tvaru

  1. Vytvořte instanci třídy GeometryShape a nastavte typ ShapeType.Rectangle.
  2. Získejte instanci třídy GeometryPath ze tvaru.
  3. Přidejte nový bod mezi dvěma horními body v cestě.
  4. Přidejte nový bod mezi dvěma dolními body v cestě.
  5. Aplikujte cestu na tvar.

Tento C++ kód vám ukazuje, jak přidat vlastní body do tvaru:

SharedPtr<Presentation> pres = System::MakeObject<Presentation>();

SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Rectangle, 100.0f, 100.0f, 200.0f, 100.0f));

SharedPtr<IGeometryPath> geometryPath = shape->GetGeometryPaths()->idx_get(0);

geometryPath->LineTo(100.0f, 50.0f, 1);
geometryPath->LineTo(100.0f, 50.0f, 4);
shape->SetGeometryPath(geometryPath);

example1_image

Odstranění bodů z tvaru

  1. Vytvořte instanci třídy GeometryShape a nastavte typ ShapeType.Heart.
  2. Získejte instanci třídy GeometryPath ze tvaru.
  3. Odstraňte segment cesty.
  4. Aplikujte cestu na tvar.

Tento C++ kód vám ukazuje, jak odstranit body z tvaru:

SharedPtr<Presentation> pres = System::MakeObject<Presentation>();

SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Heart, 100.0f, 100.0f, 300.0f, 300.0f));

SharedPtr<IGeometryPath> path = shape->GetGeometryPaths()->idx_get(0);
path->RemoveAt(2);
shape->SetGeometryPath(path);

example2_image

Vytvoření vlastního tvaru

  1. Vypočítejte body pro tvar.
  2. Vytvořte instanci třídy GeometryPath.
  3. Naplněte cestu body.
  4. Vytvořte instanci třídy GeometryShape.
  5. Aplikujte cestu na tvar.

Tento C++ kód vám ukazuje, jak vytvořit vlastní tvar:

SharedPtr<List<PointF>> points = System::MakeObject<List<PointF>>();

float R = 100.0f, r = 50.0f;
int32_t step = 72;

for (int32_t angle = -90; angle < 270; angle += step)
{
    double radians = angle * (Math::PI / 180.f);
    double x = outerRadius * Math::Cos(radians);
    double y = outerRadius * Math::Sin(radians);
    points->Add(PointF((float)x + outerRadius, (float)y + outerRadius));

    radians = Math::PI * (angle + step / 2) / 180.0;
    x = innerRadiusr * Math::Cos(radians);
    y = innerRadiusr * Math::Sin(radians);
    points->Add(PointF((float)x + outerRadius, (float)y + outerRadius));
}

SharedPtr<GeometryPath> starPath = System::MakeObject<GeometryPath>();
starPath->MoveTo(points->idx_get(0));

for (int32_t i = 1; i < points->get_Count(); i++)
{
    starPath->LineTo(points->idx_get(i));
}

starPath->CloseFigure();

SharedPtr<Presentation> pres = System::MakeObject<Presentation>();

SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Rectangle, 100.0f, 100.0f, R * 2, R * 2));

shape->SetGeometryPath(starPath);

example3_image

Vytvoření složeného vlastního tvaru

  1. Vytvořte instanci třídy GeometryShape.
  2. Vytvořte první instanci třídy GeometryPath.
  3. Vytvořte druhou instanci třídy GeometryPath.
  4. Aplikujte cesty na tvar.

Tento C++ kód vám ukazuje, jak vytvořit složený vlastní tvar:

SharedPtr<Presentation> pres = System::MakeObject<Presentation>();

SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Rectangle, 100.0f, 100.0f, 200.0f, 100.0f));

SharedPtr<IGeometryPath> geometryPath0 = System::MakeObject<GeometryPath>();
geometryPath0->MoveTo(0.0f, 0.0f);
geometryPath0->LineTo(shape->get_Width(), 0.0f);
geometryPath0->LineTo(shape->get_Width(), shape->get_Height() / 3);
geometryPath0->LineTo(0.0f, shape->get_Height() / 3);
geometryPath0->CloseFigure();

SharedPtr<IGeometryPath> geometryPath1 = System::MakeObject<GeometryPath>();
geometryPath1->MoveTo(0.0f, shape->get_Height() / 3 * 2);
geometryPath1->LineTo(shape->get_Width(), shape->get_Height() / 3 * 2);
geometryPath1->LineTo(shape->get_Width(), shape->get_Height());
geometryPath1->LineTo(0.0f, shape->get_Height());
geometryPath1->CloseFigure();

shape->SetGeometryPaths(System::MakeArray<SharedPtr<IGeometryPath>>({ geometryPath0, geometryPath1 }));

example4_image

Vytvoření vlastního tvaru s zakřivenými rohy

Tento C++ kód vám ukazuje, jak vytvořit vlastní tvar se zakřivenými rohy (dovnitř);

float shapeX = 20.f;
float shapeY = 20.f;
float shapeWidth = 300.f;
float shapeHeight = 200.f;

float leftTopSize = 50.f;
float rightTopSize = 20.f;
float rightBottomSize = 40.f;
float leftBottomSize = 10.f;

auto presentation = System::MakeObject<Presentation>();

auto childShape = presentation->get_Slides()->idx_get(0)->get_Shapes()->AddAutoShape(ShapeType::Custom, shapeX, shapeY, shapeWidth, shapeHeight);

auto geometryPath = System::MakeObject<GeometryPath>();

PointF point1(leftTopSize, 0.0f);
PointF point2(shapeWidth - rightTopSize, 0.0f);
PointF point3(shapeWidth, shapeHeight - rightBottomSize);
PointF point4(leftBottomSize, shapeHeight);
PointF point5(0.0f, leftTopSize);

geometryPath->MoveTo(point1);
geometryPath->LineTo(point2);
geometryPath->ArcTo(rightTopSize, rightTopSize, 180.0f, -90.0f);
geometryPath->LineTo(point3);
geometryPath->ArcTo(rightBottomSize, rightBottomSize, -90.0f, -90.0f);
geometryPath->LineTo(point4);
geometryPath->ArcTo(leftBottomSize, leftBottomSize, 0.0f, -90.0f);
geometryPath->LineTo(point5);
geometryPath->ArcTo(leftTopSize, leftTopSize, 90.0f, -90.0f);

geometryPath->CloseFigure();

childShape->SetGeometryPath(geometryPath);

presentation->Save(u"output.pptx", SaveFormat::Pptx);

Zjistit, zda je geometrie tvaru uzavřená

Uzavřený tvar je definován jako takový, kde všechny jeho strany jsou propojené, tvorí jednotnou hranici bez mezer. Takový tvar může být jednoduchý geometrický tvar nebo složitý vlastní obrys. Následující ukázkový kód ukazuje, jak zkontrolovat, zda je geometrie tvaru uzavřená:

bool IsGeometryClosed(SharedPtr<IGeometryShape> geometryShape)
{
    bool isClosed = false;

    for (auto&& geometryPath : geometryShape->GetGeometryPaths())
    {
        auto dataLength = geometryPath->get_PathData()->get_Length();
        if (dataLength == 0)
            continue;

        auto lastSegment = geometryPath->get_PathData()[dataLength - 1];
        isClosed = lastSegment->get_PathCommand() == PathCommandType::Close;

        if (!isClosed)
            return false;
    }

    return isClosed;
}

Převod GeometryPath na GraphicsPath

  1. Vytvořte instanci třídy GeometryShape.
  2. Vytvořte instanci třídy GraphicsPath ze jmenného prostoru System.Drawing.Drawing2D.
  3. Převěďte instanci GraphicsPath na instanci GeometryPath pomocí ShapeUtil.
  4. Aplikujte cesty na tvar.

Tento C++ kód — implementace výše uvedených kroků — ukazuje proces převodu GeometryPath na GraphicsPath:

SharedPtr<Presentation> pres = System::MakeObject<Presentation>();

SharedPtr<IShapeCollection> shapes = pres->get_Slides()->idx_get(0)->get_Shapes();
SharedPtr<GeometryShape> shape = System::ExplicitCast<GeometryShape>(shapes->AddAutoShape(ShapeType::Rectangle, 100.0f, 100.0f, 300.0f, 100.0f));

SharedPtr<IGeometryPath> originalPath = shape->GetGeometryPaths()->idx_get(0);
originalPath->set_FillMode(PathFillModeType::None);

SharedPtr<Drawing2D::GraphicsPath> graphicsPath = System::MakeObject<Drawing2D::GraphicsPath>();
graphicsPath->AddString(u"Text in shape", System::MakeObject<FontFamily>(u"Arial"), 1, 40.0f, PointF(10.0f, 10.0f), StringFormat::get_GenericDefault());

SharedPtr<IGeometryPath> textPath = ShapeUtil::GraphicsPathToGeometryPath(graphicsPath);
textPath->set_FillMode(PathFillModeType::Normal);

shape->SetGeometryPaths(System::MakeArray<SharedPtr<IGeometryPath>>({ originalPath, textPath }));

example5_image

Často kladené otázky

Co se stane s výplní a obrysem po nahrazení geometrie?

Styl zůstává u tvaru; mění se jen obrys. Výplň a obrys jsou automaticky aplikovány na novou geometrii.

Jak správně otočit vlastní tvar spolu s jeho geometrií?

Použijte vlastnost rotation tvaru; geometrie se otáčí spolu s tvarem, protože je svázána s vlastním souřadnicovým systémem tvaru.

Mohu převést vlastní tvar na obrázek, abych „uzamkl“ výsledek?

Ano. Exportujte požadovanou oblast slide nebo samotný shape do rastrového formátu; to usnadní další práci s rozsáhlými geometriemi.