• R/O
  • HTTP
  • SSH
  • HTTPS

提交

標籤
無標籤

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

作図ソフト dia の改良版


Commit MetaInfo

修訂42cde4cb7ad762284d39abb5d9de56f668c9796b (tree)
時間2014-06-08 17:58:16
作者Hans Breuer <hans@breu...>
CommiterHans Breuer

Log Message

Misc - Ngon: special handling for Hexagram and more

Drawing a crossing star take a little more points to be properly filled
if the number of rays and windings are not relatively prime. Some more
code needed to do that for {n/3} and higher.
See http://en.wikipedia.org/wiki/Star_polygon for more details.

Change Summary

差異

--- a/lib/geometry.c
+++ b/lib/geometry.c
@@ -518,6 +518,23 @@ void point_perp(Point *p, real a, real b, real c, Point *perp) {
518518 return;
519519 }
520520
521+gboolean
522+line_line_intersection (Point *crossing,
523+ const Point *p1, const Point *p2,
524+ const Point *p3, const Point *p4)
525+{
526+ real d = (p1->x - p2->x) * (p3->y - p4->y) - (p1->y - p2->y) * (p3->x - p4->x);
527+ real a, b;
528+
529+ if (fabs(d) < 0.0000001)
530+ return FALSE;
531+ a = p1->x * p2->y - p1->y * p2->x;
532+ b = p3->x * p4->y - p3->y * p4->x;
533+ crossing->x = (a * (p3->x - p4->x) - (p1->x - p2->x) * b) / d;
534+ crossing->y = (a * (p3->y - p4->y) - (p1->y - p2->y) * b) / d;
535+ return TRUE;
536+}
537+
521538 /* Compute a circular arc fillet between lines L1 (p1 to p2)
522539 and L2 (p3 to p4) with radius r.
523540 The circle center is c.
--- a/lib/geometry.h
+++ b/lib/geometry.h
@@ -377,6 +377,9 @@ void transform_bezpoint (BezPoint *bpt, const DiaMatrix *m);
377377 real dot2(Point *p1, Point *p2);
378378 void line_coef(real *a, real *b, real *c, Point *p1, Point *p2);
379379 real line_to_point(real a, real b , real c, Point *p);
380+gboolean line_line_intersection (Point *crossing,
381+ const Point *p1, const Point *p2,
382+ const Point *p3, const Point *p4);
380383 void point_perp(Point *p, real a, real b, real c, Point *perp);
381384 gboolean fillet(Point *p1, Point *p2, Point *p3, Point *p4,
382385 real r, Point *c, real *pa, real *aa);
--- a/lib/libdia.def
+++ b/lib/libdia.def
@@ -523,6 +523,7 @@ EXPORTS
523523 new_layer
524524
525525 line_bbox
526+ line_line_intersection
526527
527528 dia_error_quark
528529
--- a/objects/Misc/n_gon.c
+++ b/objects/Misc/n_gon.c
@@ -364,10 +364,9 @@ _ngon_make_name (Ngon *ng)
364364 /*!
365365 * \brief Sort points to produce a star with crossing edges
366366 *
367- * We could support the different possibilities explained by
367+ * We support the different possibilities explained by
368368 * http://en.wikipedia.org/wiki/Star_polygon
369- * but first need a good user interface to select between this
370- * number of point dependent selection.
369+ * via the density parameter mostly.
371370 */
372371 static void
373372 _ngon_adjust_for_crossing (Ngon *ng)
@@ -380,10 +379,35 @@ _ngon_adjust_for_crossing (Ngon *ng)
380379 g_array_insert_vals (points, 0,
381380 &g_array_index (ng->points, Point, 0),
382381 ng->points->len);
383- for (i = 1; i < n; ++i) {
384- int j = (i * step) % n;
385- g_array_index (ng->points, Point, i).x = g_array_index (points, Point, j).x;
386- g_array_index (ng->points, Point, i).y = g_array_index (points, Point, j).y;
382+ if (1 == step && n > 5 && (n % 2) == 0) {
383+ /* calculate the crossing of edges as extra point */
384+ Point crossing;
385+ if (!line_line_intersection (&crossing,
386+ &g_array_index (points, Point, 0), &g_array_index (points, Point, n-2),
387+ &g_array_index (points, Point, 1), &g_array_index (points, Point, n-1)))
388+ g_warning ("No intersection?");
389+ step = 2;
390+ for (i = 0; i < n/2; ++i) {
391+ int j = (i * step) % n;
392+ g_array_index (ng->points, Point, i).x = g_array_index (points, Point, j).x;
393+ g_array_index (ng->points, Point, i).y = g_array_index (points, Point, j).y;
394+ }
395+ /* go backward for the second half */
396+ for (i = 0; i < n/2; ++i) {
397+ int j = (n - 1 - i * step) % n;
398+ g_array_index (ng->points, Point, i + n/2).x = g_array_index (points, Point, j).x;
399+ g_array_index (ng->points, Point, i + n/2).y = g_array_index (points, Point, j).y;
400+ }
401+ /* insert the crossing point at the end */
402+ g_array_insert_val (ng->points, n, crossing);
403+ /* insert the crossing point in the middle */
404+ g_array_insert_val (ng->points, n/2, crossing);
405+ } else {
406+ for (i = 1; i < n; ++i) {
407+ int j = (i * step) % n;
408+ g_array_index (ng->points, Point, i).x = g_array_index (points, Point, j).x;
409+ g_array_index (ng->points, Point, i).y = g_array_index (points, Point, j).y;
410+ }
387411 }
388412 g_array_free (points, TRUE);
389413 }
@@ -405,11 +429,15 @@ _ngon_update_data (Ngon *ng)
405429 n = ng->num_rays * 2;
406430
407431 /* ensure density stays in range */
408- if (ng->last_density > ng->density)
409- ng->density = _calc_step (ng->num_rays, ng->density);
410- else
432+ if (ng->last_density > ng->density) {
433+ real temp = _calc_step (ng->num_rays, ng->density);
434+ /* special case for Hexagram and above */
435+ if (temp == 1 && ng->kind == NGON_CROSSING && ng->num_rays > 5)
436+ temp = 2;
437+ ng->density = temp;
438+ } else {
411439 ng->density = _calc_step_up (ng->num_rays, ng->density);
412-
440+ }
413441 _ngon_make_name (ng);
414442 if (1 || n != ng->points->len) {
415443 /* recalculate all points */