{"id":25301,"date":"2016-05-05T18:22:31","date_gmt":"2016-05-05T22:22:31","guid":{"rendered":"http:\/\/www.shapeways.com\/blog\/?p=25301"},"modified":"2016-05-05T18:22:31","modified_gmt":"2016-05-05T22:22:31","slug":"learn-shapejs-symmetry-and-reflections-part-1","status":"publish","type":"post","link":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1","title":{"rendered":"Learn ShapeJS: Symmetry and Reflections Part 1"},"content":{"rendered":"<p>For this week we\u2019ll start into the powerful world of symmetry and reflections.  ShapeJS allows arbitrary transformations of objects and as we\u2019ll see in this post this has great power and some sharp edges to avoid.  Guest writing this week is Vladimir Bulatov, he\u2019s the math whiz behind the curtains of ShapeJS.<\/p>\n<p><b>PeriodicWrap<\/b> is a ShapeJS transformation which is most useful for creating repeated shapes and patterns. However if used incorrectly it can produce unexpected results. The purpose of this tutorial is to provide basic info and examples with correct use of PeriodicWrap, highlight potential problems and suggest possible solutions.<\/p>\n<p>PeriodicWrap generates a fill of the three dimensional space (tiling) with copies of a single tile &#8211; the fundamental domain. PeriodicWrap is defined by linearly independent basis vectors and an origin. All parameters have type Vector3d. Basis vectors define the shape and orientation of the fundamental domain and the origin defines the place of the fundamental domain in space. There are 3 variants of PeriodicWrap one-, two- and three-periodic.  This week we\u2019ll examine the one periodic version, and in a later post we\u2019ll cover the more complex versions.  <\/p>\n<p><Strong>One-periodic wrap<\/Strong><br \/>\nWe start with the simplest variant &#8211; one-periodic.  It is defined by one basis vector and origin. The origin has default value (0,0,0) which means the PeriodicWrap is located at the origin of the coordinate axes.<\/p>\n<style type=\"text\/css\">\ncode,pre{font-family:menlo, monaco, \"andale mono\", \"courier new\", fixed;font-size:0.9em;line-height:18px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;-ms-border-radius:4px;border-radius:4px}pre{padding:10px;white-space:pre-wrap;text-shadow:none;}pre.attach{margin-top:-25px;border-radius:0 0 5px 5px;padding-top:15px}code.dark{padding:.2em .4em;background:#3f4d82;color:#ebecfc;white-space:nowrap}pre code{padding:0;background:none;-webkit-border-radius:0;-moz-border-radius:0;-ms-border-radius:0;border-radius:0;}code{padding:.2em .4em;background:rgba(0,0,0,0.03);font-family:menlo, monaco, \"andale mono\", \"courier new\", fixed;-webkit-border-radius:3px;-moz-border-radius:3px;-ms-border-radius:3px;border-radius:3px;white-space:nowrap}pre{display:block;background-color:#333;color:#ffffff}}<\/p>\n<p>.iframe{\n    margin-left: -446px;\n    width: 1360px;\n}\n<\/style>\n<pre class=\"code\">var a = 5*MM;\r\nvar pw = new PeriodicWrap(new Vector3d(a,0,0));\r\n<\/pre>\n<p>This creates a one dimensional PeriodicWrap with basis vector (a,0,0). <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_01_diagram.png\" \/><\/p>\n<p>The one-periodic tiling can be imagined as cutting a space into set of identical slices. The fundamental domain (yellow) is a single slice. Slices are orthogonal to the basis vector (in this case (a,0,0). The thickness of the slice equals the length of the basis vector (5mm in this case) and the left side of the slice passes through the origin of the PeriodicWrap (in this case default value (0,0,0)).  Let\u2019s place a simple shape inside of the fundamental domain. <\/p>\n<pre class=\"code\">\r\n  var sphere = new Sphere(a\/2,a\/2,0, a\/3); \/\/ sphere radius a\/3 centered at (a\/2,a\/2, 0) \r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_02_shape.png\" \/><br \/>\nAnd apply PeriodicWrap to the shape. <\/p>\n<pre class=\"code\">\r\n  sphere.setTransform(pw); \/\/ tiled sphere \r\n<\/pre>\n<p>Here is the diagram of the result: <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_03_tiling_1D.png\" \/><br \/>\nShapes are replicated in both directions indefinitely. Below is the screenshot of the ShapeJS rendering:<br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_03_tiling_1D_rend.png\" \/><br \/>\nLet\u2019s place a different shape in a different spot<\/p>\n<pre class=\"code\">\r\n  var redSphere = new Sphere(0,a\/3,0,a\/2); \/\/ sphere radius a\/2 centered at (0,a\/3,0)\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_04_red_shape_1D.png\" \/><\/p>\n<p>PeriodicWrap works by filling the whole space by identical copies of single tile &#8211; the fundamental domain.The interior of the fundamental domain is replicated. Parts of the shape outside of fundamental domain are cropped. It means, that the half of sphere sitting outside of fundamental domain abruptly disappears.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_05_red_shape_tiled_1D.png\" \/><br \/>\nThe rendering looks even worse, the cropping induces severe rendering artifacts<br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_05_red_shape_tiled_1D_rend.png\" \/><\/p>\n<p>There is a simple solution to the problem. We can shift the origin of the tiling to make a shape enclosed by the fundamental domain<\/p>\n<pre class=\"code\">\r\n  pw.setOrigin(new Vector3d(-a\/2,0,0));\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_06_red_shape_shifted_origin.png\" \/><br \/>\nAnd here is the tiling<br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_08_red_shape_shifted_tiling.png\" \/><br \/>\nThe rendering now looks correct as well<br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_08_red_shape_shifted_tiling_rend.png\" \/><\/p>\n<p>But it is not always possible to select a good location for the tilings origin. In example below we have a union of two shapes.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_09_double_shape.png\" \/><\/p>\n<p>The union doesn\u2019t fit inside of fundamental domain. Therefore the shape always will be partially cropped:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_10_double_shape_cropped.png\" \/><br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_10_double_shape_cropped_rend.png\" \/><\/p>\n<p>The solution to the problem is to build a shape inside of the fundamental domain in a way which will compensate for unavoidable cropping: the opposite sides of fundamental domain have to pair seamlessly to each other. In this case we can place copy of another red sphere translated by the tiling basis vector (a,0,0)<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_11_double_shape_corrected.png\" \/><br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_11_double_shape_corrected_rend.png\" \/><\/p>\n<p>Here are the drawing and rendering of the resulting tiling:<\/p>\n<p>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_12_double_shape_tiled.png\" \/><br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_12_double_shape_tiled_rend.png\" \/><br \/>\nComplete ShapeJS script of the example with two shapes:<\/p>\n<pre class=\"code\">\r\nfunction main(args) {\t\r\n  var w = 30*MM; \/\/ scene size\r\n  var a = 5*MM; \/\/ period of wrap \r\n  var s1 = new Sphere(a\/2, a\/2, 0, a\/3);  \/\/ shape 1\r\n  var s2 = new Sphere(0, 0.7*a, 0, a\/2);  \/\/ shape 2\r\n  var s2t = new Sphere(a, 0.7*a, 0, a\/2); \/\/ translated shape 2\r\n  var pw = new PeriodicWrap(new Vector3d(a,0,0));  \r\n  var shape = new Union(s1, s2);\r\n  shape.add(s2t);\r\n  shape.setTransform(pw);  \r\n  return new Scene(shape,new Bounds(-w,w,-w,w,-w,w));\r\n}\r\n<\/pre>\n<p>After a PeriodicWrap transform is applied to a shape inside of the fundamental domain we normally obtain an unbounded shape. That shape intersects the scene bounds and as result has an open interior, which results in manifold problems in the generated mesh as is shown below with red. <\/p>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_12_double_shape_tiled_rend1.png\" \/><\/p>\n<p>In order to obtain a finite shape of specific size, we may intersect unbounded shape with some shape of specific size, for example a box: <\/p>\n<pre class=\"code\">\r\nshape = new Intersection(shape, new Box(55*MM, 20*MM, 20*MM));\r\n<\/pre>\n<p><img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw_12_double_shape_tiled_rend2.png\" \/><br \/>\nPeriodWraps are a powerful method for creating many copies of your geometry.  It&#8217;s also a much more efficient way to create lots of shapes instead of copying the datasources.  In our next posting on symmetry and reflections we\u2019ll explore the two and three periodic wrappings.  These allow you to create some interesting patterns, similar to what you might find in nature.  As a taste here are some two and three periodic wrappings:<br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw2_grid_in_circle.png\" \/><br \/>\n<img decoding=\"async\" src=\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/pw3_grid_in_sphere.png\" \/><\/p>\n","protected":false},"excerpt":{"rendered":"<p>For this week we\u2019ll start into the powerful world of symmetry and reflections. ShapeJS allows arbitrary transformations of objects and&#8230;<\/p>\n","protected":false},"author":20,"featured_media":25334,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[520,502,486],"class_list":["post-25301","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","tag-46-api","tag-26-customization","tag-10-software"],"thumbnail":"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg","yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v23.9 (Yoast SEO v23.9) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Learn ShapeJS: Symmetry and Reflections Part 1 - Shapeways Blog<\/title>\n<meta name=\"description\" content=\"For this week we\u2019ll start into the powerful world of symmetry and reflections. ShapeJS allows arbitrary transformations of objects and as we\u2019ll see in\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Alan Hudson\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1\"},\"author\":{\"name\":\"Alan Hudson\",\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/person\/f05fffb15133508e96bed53d690aaa35\"},\"headline\":\"Learn ShapeJS: Symmetry and Reflections Part 1\",\"datePublished\":\"2016-05-05T22:22:31+00:00\",\"dateModified\":\"2016-05-05T22:22:31+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1\"},\"wordCount\":724,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg\",\"keywords\":[\"API\",\"Customization\",\"Software\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1\",\"url\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1\",\"name\":\"Learn ShapeJS: Symmetry and Reflections Part 1 - Shapeways Blog\",\"isPartOf\":{\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg\",\"datePublished\":\"2016-05-05T22:22:31+00:00\",\"dateModified\":\"2016-05-05T22:22:31+00:00\",\"description\":\"For this week we\u2019ll start into the powerful world of symmetry and reflections. ShapeJS allows arbitrary transformations of objects and as we\u2019ll see in\",\"breadcrumb\":{\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#primaryimage\",\"url\":\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg\",\"contentUrl\":\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg\",\"width\":625,\"height\":465},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/prodshapeblog.wpenginepowered.com\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Learn ShapeJS: Symmetry and Reflections Part 1\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#website\",\"url\":\"https:\/\/prodshapeblog.wpenginepowered.com\/\",\"name\":\"Shapeways Blog\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/prodshapeblog.wpenginepowered.com\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#organization\",\"name\":\"Shapeways Blog\",\"url\":\"https:\/\/prodshapeblog.wpenginepowered.com\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2019\/05\/shapeways-blog.png\",\"contentUrl\":\"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2019\/05\/shapeways-blog.png\",\"width\":943,\"height\":121,\"caption\":\"Shapeways Blog\"},\"image\":{\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"http:\/\/facebook.com\/shapeways\",\"https:\/\/x.com\/shapeways\",\"http:\/\/instagram.com\/shapeways\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/person\/f05fffb15133508e96bed53d690aaa35\",\"name\":\"Alan Hudson\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/d1a9aaa014d64d6af1b35e31f3765903e93974bbcc471d40c8b9d03a123db6a7?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/d1a9aaa014d64d6af1b35e31f3765903e93974bbcc471d40c8b9d03a123db6a7?s=96&d=mm&r=g\",\"caption\":\"Alan Hudson\"},\"url\":\"https:\/\/www.shapeways.com\/blog\/author\/alan\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"Learn ShapeJS: Symmetry and Reflections Part 1 - Shapeways Blog","description":"For this week we\u2019ll start into the powerful world of symmetry and reflections. ShapeJS allows arbitrary transformations of objects and as we\u2019ll see in","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1","twitter_misc":{"Written by":"Alan Hudson","Est. reading time":"4 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#article","isPartOf":{"@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1"},"author":{"name":"Alan Hudson","@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/person\/f05fffb15133508e96bed53d690aaa35"},"headline":"Learn ShapeJS: Symmetry and Reflections Part 1","datePublished":"2016-05-05T22:22:31+00:00","dateModified":"2016-05-05T22:22:31+00:00","mainEntityOfPage":{"@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1"},"wordCount":724,"commentCount":0,"publisher":{"@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#organization"},"image":{"@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#primaryimage"},"thumbnailUrl":"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg","keywords":["API","Customization","Software"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1","url":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1","name":"Learn ShapeJS: Symmetry and Reflections Part 1 - Shapeways Blog","isPartOf":{"@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#primaryimage"},"image":{"@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#primaryimage"},"thumbnailUrl":"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg","datePublished":"2016-05-05T22:22:31+00:00","dateModified":"2016-05-05T22:22:31+00:00","description":"For this week we\u2019ll start into the powerful world of symmetry and reflections. ShapeJS allows arbitrary transformations of objects and as we\u2019ll see in","breadcrumb":{"@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#primaryimage","url":"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg","contentUrl":"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2016\/05\/three_periodic.jpg","width":625,"height":465},{"@type":"BreadcrumbList","@id":"https:\/\/www.shapeways.com\/blog\/learn-shapejs-symmetry-and-reflections-part-1#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/prodshapeblog.wpenginepowered.com\/"},{"@type":"ListItem","position":2,"name":"Learn ShapeJS: Symmetry and Reflections Part 1"}]},{"@type":"WebSite","@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#website","url":"https:\/\/prodshapeblog.wpenginepowered.com\/","name":"Shapeways Blog","description":"","publisher":{"@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/prodshapeblog.wpenginepowered.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#organization","name":"Shapeways Blog","url":"https:\/\/prodshapeblog.wpenginepowered.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2019\/05\/shapeways-blog.png","contentUrl":"https:\/\/www.shapeways.com\/blog\/wp-content\/uploads\/2019\/05\/shapeways-blog.png","width":943,"height":121,"caption":"Shapeways Blog"},"image":{"@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/logo\/image\/"},"sameAs":["http:\/\/facebook.com\/shapeways","https:\/\/x.com\/shapeways","http:\/\/instagram.com\/shapeways"]},{"@type":"Person","@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/person\/f05fffb15133508e96bed53d690aaa35","name":"Alan Hudson","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/prodshapeblog.wpenginepowered.com\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/d1a9aaa014d64d6af1b35e31f3765903e93974bbcc471d40c8b9d03a123db6a7?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/d1a9aaa014d64d6af1b35e31f3765903e93974bbcc471d40c8b9d03a123db6a7?s=96&d=mm&r=g","caption":"Alan Hudson"},"url":"https:\/\/www.shapeways.com\/blog\/author\/alan"}]}},"_links":{"self":[{"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/posts\/25301","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/users\/20"}],"replies":[{"embeddable":true,"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/comments?post=25301"}],"version-history":[{"count":0,"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/posts\/25301\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/media\/25334"}],"wp:attachment":[{"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/media?parent=25301"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/categories?post=25301"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.shapeways.com\/blog\/wp-json\/wp\/v2\/tags?post=25301"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}