Σχεδίαση καμπύλων γραμμών

Πέρα από τη σχεδίαση ευθειών γραμμών το Cairo επιτρέπει την εύκολη σχεδίαση καμπύλων γραμμών (τεχνικά μια κυβική εύκαμπτη καμπύλη Bézier) χρησιμοποιώντας τις συναρτήσεις Cairo::Context::curve_to() και Cairo::Context::rel_curve_to(). Αυτές οι συναρτήσεις παίρνουν συντεταγμένες για ένα σημείο προορισμού καθώς και συντεταγμένες για δύο σημεία 'ελέγχου'. Αυτό εξηγείται καλύτερα χρησιμοποιώντας ένα παράδειγμα, έτσι ας μπούμε μέσα.

17.3.1. Παράδειγμα

Αυτή η απλή εφαρμογή σχεδιάζει μια καμπύλη με Cairo και εμφανίζει τα σημεία ελέγχου για κάθε άκρο της καμπύλης.

Φιγούρα 17-4Περιοχή σχεδίασης - Γραμμές

Source Code

File: myarea.h (For use with gtkmm 3, not gtkmm 2)

#ifndef GTKMM_EXAMPLE_MYAREA_H
#define GTKMM_EXAMPLE_MYAREA_H

#include <gtkmm/drawingarea.h>

class MyArea : public Gtk::DrawingArea
{
public:
  MyArea();
  virtual ~MyArea();

protected:
  //Override default signal handler:
  bool on_draw(const Cairo::RefPtr<Cairo::Context>& cr) override;
};

#endif // GTKMM_EXAMPLE_MYAREA_H

File: myarea.cc (For use with gtkmm 3, not gtkmm 2)

#include "myarea.h"
#include <cairomm/context.h>

MyArea::MyArea()
{
}

MyArea::~MyArea()
{
}

bool MyArea::on_draw(const Cairo::RefPtr<Cairo::Context>& cr)
{
  Gtk::Allocation allocation = get_allocation();
  const int width = allocation.get_width();
  const int height = allocation.get_height();

  double x0=0.1, y0=0.5, // start point
         x1=0.4, y1=0.9,  // control point #1
         x2=0.6, y2=0.1,  // control point #2
         x3=0.9, y3=0.5;  // end point

  // scale to unit square (0 to 1 width and height)
  cr->scale(width, height);

  cr->set_line_width(0.05);
  // draw curve
  cr->move_to(x0, y0);
  cr->curve_to(x1, y1, x2, y2, x3, y3);
  cr->stroke();
  // show control points
  cr->set_source_rgba(1, 0.2, 0.2, 0.6);
  cr->move_to(x0, y0);
  cr->line_to (x1, y1);
  cr->move_to(x2, y2);
  cr->line_to (x3, y3);
  cr->stroke();

  return true;
}

File: main.cc (For use with gtkmm 3, not gtkmm 2)

#include "myarea.h"
#include <gtkmm/application.h>
#include <gtkmm/window.h>

int main(int argc, char** argv)
{
   auto app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

   Gtk::Window win;
   win.set_title("DrawingArea");

   MyArea area;
   win.add(area);
   area.show();

   return app->run(win);
}

Η μόνη διαφορά μεταξύ αυτού του παραδείγματος και του παραδείγματος της ευθείας γραμμής είναι στη συνάρτηση on_draw(), αλλά υπάρχουν λίγες νέες έννοιες και συναρτήσεις που εισήχθησαν εδώ, έτσι ας τις εξετάσουμε συνοπτικά.

Κάνουμε μια κλήση στη Cairo::Context::scale(), περνώντας το πλάτος και το ύψος της περιοχής σχεδίασης. Αυτό κλιμακώνει το σύστημα συντεταγμένων χώρου χρήστη, έτσι ώστε το πλάτος και το ύψος του γραφικού συστατικού να είναι ίσα με 1.0 'μονάδες'. Δεν υπάρχει ειδικός λόγος να κλιμακώσουμε το σύστημα συντεταγμένων σε αυτήν την περίπτωση, αλλά μερικές φορές μπορεί να κάνουμε τη σχεδίαση λειτουργιών ευκολότερα.

Η κλήση στη Cairo::Context::curve_to() πρέπει να είναι επαρκώς αυτονόητη. Το πρώτο ζεύγος συντεταγμένων ορίζει το σημείο ελέγχου για την αρχή της καμπύλης. Το δεύτερο σύνολο των συντεταγμένων ορίζει το σημείο ελέγχου για το τέλος της καμπύλης και το τελευταίο σύνολο συντεταγμένων ορίζει το σημείο προορισμού. Για τη διευκόλυνση της έννοιας των σημείων ελέγχου στην οπτικοποίηση, μια γραμμή έχει σχεδιαστεί από κάθε σημείο ελέγχου στο τελικό σημείο της καμπύλης με το οποίο σχετίζεται. Σημειώστε ότι αυτές οι γραμμές σημείων ελέγχου είναι και οι δυο ημιδιαφανείς. Αυτό πετυχαίνεται με μια παραλλαγή της set_source_rgb() που λέγεται set_source_rgba(). Αυτή η συνάρτηση παίρνει ένα τέταρτο όρισμα που ορίζει την τιμή άλφα του χρώματος (έγκυρες τιμές είναι μεταξύ 0 και 1).