Skip to content

Conversation

@HansOlsson
Copy link
Collaborator

Closes #1826

@HansOlsson HansOlsson requested a review from henrikt-ma December 4, 2025 08:19
Copy link
Collaborator

@maltelenz maltelenz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are libraries out there that use this, and it is clearly useful, so removing this feature is not reasonable.

Example usage of HorizontalCylinder on a Polygon:

Image
model Package
  annotation(
    Icon(
      coordinateSystem(extent = {{-100, -100}, {100, 100}}, grid = {10, 10}),
      graphics = {
        Polygon(origin = {0.248, 0.044}, lineColor = {56, 56, 56}, fillColor = {128, 202, 255}, fillPattern = FillPattern.Solid, points = {{99.752, 100}, {99.752, 59.956}, {99.752, -50}, {100, -100}, {49.752, -100}, {-19.752, -100.044}, {-100.248, -100}, {-100.248, -50}, {-90.248, 29.956}, {-90.248, 79.956}, {-40.248, 79.956}, {-20.138, 79.813}, {-0.248, 79.956}, {19.752, 99.956}, {39.752, 99.956}, {59.752, 99.956}}, smooth = Smooth.Bezier),
        Polygon(origin = {0, -13.079}, lineColor = {192, 192, 192}, fillColor = {255, 255, 255}, pattern = LinePattern.None, fillPattern = FillPattern.HorizontalCylinder, points = {{100, -86.921}, {50, -86.921}, {-50, -86.921}, {-100, -86.921}, {-100, -36.921}, {-100, 53.079}, {-100, 103.079}, {-50, 103.079}, {0, 103.079}, {20, 83.079}, {50, 83.079}, {100, 83.079}, {100, 33.079}, {100, -36.921}}, smooth = Smooth.Bezier),
        Polygon(origin = {0, -10.704}, lineColor = {113, 113, 113}, fillColor = {255, 255, 255}, points = {{100, -89.296}, {50, -89.296}, {-50, -89.296}, {-100, -89.296}, {-100, -39.296}, {-100, 50.704}, {-100, 100.704}, {-50, 100.704}, {0, 100.704}, {20, 80.704}, {50, 80.704}, {100, 80.704}, {100, 30.704}, {100, -39.296}}, smooth = Smooth.Bezier)
      }
    )
  );
end Package;

@henrikt-ma
Copy link
Collaborator

The best way to proceed might then be to let the tools that have implemented this describe what they do, so that we can see if the implementations have something in common that we can agree upon?

@henrikt-ma henrikt-ma removed their request for review December 4, 2025 11:17
@d-hedberg
Copy link

We have libraries using these fill patterns on polygons. Why would we restrict/remove something that clearly is useful?

@HansOlsson
Copy link
Collaborator Author

The best way to proceed might then be to let the tools that have implemented this describe what they do, so that we can see if the implementations have something in common that we can agree upon?

Ok, making a table based on what I assume:

Pattern Ellipse Rectangle Polygon
Solid etc Yes Yes Yes
HorizontalCylinder Dymola,WSM Dymola,WSM WSM
VerticalCylinder Dymola,WSM Dymola,WSM WSM
Sphere Dymola, Dymola, ?

It seems that the only potentially missing feature is spherical gradient for polygons, and it shouldn't be that difficult to support.
So the simplest is to just don't change anything.

@d-hedberg
Copy link

System Modeler also supports sphere fills on Polygons.

@d-hedberg
Copy link

System Modeler
image

@d-hedberg
Copy link

For sphere fill on polygons, System Modeler does:
// The center point is the center point of the polygon's bounding box.
// The radius is the distance from the polygon's center point to the vertex farthest away.


The attributes \lstinline!HorizontalCylinder!, \lstinline!VerticalCylinder! and \lstinline!Sphere! specify gradients that represent a horizontal cylinder, a vertical cylinder and a sphere, respectively.
The gradient goes from line color to fill color.
The \lstinline!HorizontalCylinder! and \lstinline!VerticalCylinder! are only defined for rectangles and ellipses (not polygons), and \lstinline!Sphere! is only defined for ellipses.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
The \lstinline!HorizontalCylinder! and \lstinline!VerticalCylinder! are only defined for rectangles and ellipses (not polygons), and \lstinline!Sphere! is only defined for ellipses.
For polygons the gradients are defined on the enclosing rectangle (for \lstinline!HorizontalCylinder!, \lstinline!VerticalCylinder!) or circle (for \lstinline!Sphere!).

Trying to shortly explain how the gradients work for polygons, based on feedback.

As far as I understand "enclosing" generally means "smallest enclosing".
Note that it is subtly different that basing it on vertices (in case of splines) - as long as you don't do any weird extrapolation users will not notice.

@henrikt-ma
Copy link
Collaborator

henrikt-ma commented Dec 5, 2025

Just wondering, but wouldn't it make sense if the center and radius of the Sphere gradient were defined in such a way that they transform consistently with the rest of the shape under Euclidean transformations? (A spherical gradient with circular level curves can't transform naturally when skewing or scaling differently in different directions.)

If the center is defined so that it transforms naturally with the shape, it is natural to define the radius as the distance from the center to the controlling point furtherest away (simpler math compared to the distance to the point furtherest away on the curve delimiting the shape).

One simple definition of the center is to use the origin in the local coordinates of the shape. This also has the advantage that the user can select where to put the center.

Another option is to define the center as the center of mass of the polygon with vertices at the controlling points (simpler math compared to the center of mass of the curve delimiting the shape). For @d-hedberg's example of an equilateral triangle in #3789 (comment), this would result in the same color at all three corners of the triangle, no matter how it is rotated.

@henrikt-ma
Copy link
Collaborator

Please don't take #3789 (comment) as a concrete proposal; it has several drawbacks:

  • The idea of using the local origin will break appearance badly for existing use if the origin isn't near "the center".
  • There are many more centers of mass that could be sensible choices, even without adding the more numerically demanding ones to the list, so picking one of them would become an arbitrary design decision.
  • It would be disruptive for System Modeler users.
  • It would require implementation effort for Wolfram to comply with the specification.

One thing that I believe might help us reach agreement would be to introduce a gradientCenter attribute in FilledShape, which would be optional for Rectangle and Ellipse, defaulting to being at the obvious center of the shape. For Polygon it should be non-optional, but with a deprecated semantics of tool-specific behavior when being unspecified.

However, when thinking more about how to define the "gradient length", I realized that it wasn't clear to me how Sphere should be applied even to a non-circular Ellipse. Should it be A or B below?
ellipses

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

What is fillPattern=FillPattern.Sphere on Rectangle or Polygon?

4 participants