# How to create custom geometric object?

How to create custom geometric object?

It should have the following properties, resembling properties of built-in geometric figures, like Circle etc:

1) Has constant head, say RoundedRectangle. It should not evaluated to the list of lines, so as normal Rectangle.

2) Can serve as a subject for GeometricTransform

-
Rectangle is a function turning some parameters into a graphics object. Such a function for rounded rectangles can be found in this post: mathematica.stackexchange.com/questions/1882/… –  Pickett Jun 18 '13 at 8:19
Suzan, I don't understand what you are looking for in this question. Can you be a bit more explicit about what you are looking for? –  bill s Jun 18 '13 at 10:05
Are you asking how to define an object that Mathematica will treat as a graphic primitive such as Disk or Circle? –  m_goldberg Jun 18 '13 at 10:14
You might want to look into the old packages GraphicsArrow  or GraphicsSpline  to see how they implemented primitives that were once not built-in. –  Ｊ. Ｍ. Jun 18 '13 at 10:49
It seems that you are under a common misconception. As far as the kernel is concerned, Graphics is inert, i.e. it has no DownValues. It is only in the formatting end of things that it is turned into an image. The same applies to the primitives, like Rectangle, but they are only formatted when found within a Graphics(3D) object. So, Rectangle remains a Rectangle and GeometricTransformation can be applied to it. –  rcollyer Jun 18 '13 at 12:31

Try this:

SetAttributes[createPrimitive, HoldAll]

createPrimitive[patt_, expr_] :=
TypesetMakeBoxes[p : patt, fmt_, Graphics] :=
TypesetMakeBoxes[Interpretation[expr, p], fmt, Graphics]


Example:

createPrimitive[face[x_: 0.1],
{Circle[{0, 0}, 1], Circle[{-0.3, 0.5}, x],
Circle[{0.3, 0.5}, x], Line[{{-0.4, -0.2}, {0.4, -0.2}}]}]


It works as expected in Graphics:

g = Graphics[face[]]


face has no DownValues so it remains as face in InputForm:

InputForm[g]
(*  Graphics[face[]]  *)


(*  Graphics[face[], ImageSize -> {63., Automatic}]  *)


It works with GeometricTransformation:

Graphics[GeometricTransformation[face[0.2], ShearingTransform[Pi/4, {1, 0}, {0, 1}]]]


-
+1, I like it, and now I require a lot more letters to fulfill the 15 letter requirement. –  rcollyer Jun 18 '13 at 15:58
+1. What does TypesetMakeBoxes do exactly? (lazy to start a spelunking battle) –  Rojo Dec 13 '13 at 18:56
@Rojo, I don't understand the details, but it's used internally by MakeBoxes to convert graphics primitives to boxes. I don't think it's possible to give definitions for creating graphics boxes directly with MakeBoxes, you have to use TypesetMakeBoxes instead. –  Simon Woods Dec 13 '13 at 19:17
That's nice, thanks –  Rojo Dec 13 '13 at 22:19

I don't see how to do what you are asking for without modifying the built-in definition of Graphics, something I would be extremely reluctant to do. In my own work, the closest I have come to meeting your requirements is to define functions that define shapes by returning lists consisting of graphics directives and primitives. This has worked well enough to satisfy me so far.

Here is an example.

dashedPoly[pts : {{_, _} ..},
fill : (_RGBColor | _GrayLevel | _Hue) : Transparent] :=
{fill, EdgeForm[Dashing[Small]], Polygon[pts]}


And here are two examples of the function in use.

Module[{A, B, C},
A = {0., 0.}; B = {0., 3.}; C = {4., 0.};
Graphics[dashedPoly[{A, B, C}]]]


With[{blue = ColorData["HTML", "DeepSkyBlue"]},
Module[{A, B, C},
A = {0., 0.}; B = {0., 3.}; C = {4., 0.};
Graphics[dashedPoly[{A, B, C}, blue]]]]


-