Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Line joint rendering issues; joint algorithm not taking stroke thickness (outer curve length) into account

Explorer ,
Jun 17, 2014 Jun 17, 2014

The line joint algorithm Flash uses is underestimating the number of steps or divisions necessary to produce a smooth curve with low curve radii, because it's failing to take into account the stroke thickness.

For example, an ellipse width of 3 on a rounded rectangle would look fine using only a couple steps if the thickness was only 1 or 2 pixels, because the outside edge of the curve would only occupy 1 or 2 pixels.  However, for a larger stroke thickness such as 50, the curve produced is unacceptable.  Furthermore, at an ellipse size of 5, there's an anomalous spike in the upper left that you can see in the following example (6th shape from the left).  Really, once a non-zero value for ellipseWidth or ellipseHeight is introduced in the call to drawRoundRect, a round corner joint style is implied, so the algorithm should, for any non-zero-radius corner, include enough steps to produce a smooth curve, given a particular line thickness, along both the inside and outside edges of that curve.

line_glitches.png

There are also blatant anomalies introduced when stepping through rectangle heights of, for example, 105 through 110, such that heights of 106 and 110 have anomalous bevels instead of smooth curves in the corners.  The little light green line in the center is fine, it's just an expected rounding artifact where the green fill is not quite covered by the 50% transparent black outline.  But those corners...

line_glitches2.png

Here is the code to produce the first and second set of shapes.

import flash.display.LineScaleMode;

import flash.display.CapsStyle;

import flash.display.JointStyle;

import flash.display.StageScaleMode;

import flash.display.StageAlign;

stage.align = StageAlign.TOP_LEFT;

stage.scaleMode = StageScaleMode.NO_SCALE;

var thickness:Number = 50;

var half_thickness:Number = thickness / 2;

var lineColor:Number = 0x000000;

var lineAlpha:Number = 0.5;

var fillcolor:Number = 0x00ff00;

var fillalpha:Number = 1;

var pixelHinting:Boolean = true;

var scaleMode:String = flash.display.LineScaleMode.NORMAL;

var caps:String = flash.display.CapsStyle.SQUARE;

var joints:String = flash.display.JointStyle.MITER;

var miterLimit:Number = thickness;

var rectWidth:Number = 100;

var rectHeight:Number = 100;

var ellipseWidth:Number = 0;

var ellipseHeight:Number = 0;

var offset_x:Number = 0;

var offset_y:Number = 0;

var g:Graphics = graphics;

g.clear();

//Draw 8 sizes of rounded rectangles;

//increasing the ellipse width and height by 1 each cycle.

for (var i:int = 0; i < 8; i++)

{

    offset_x = i * (rectWidth + 10); //offset each subsequent rectangle to the right

    ellipseWidth = ellipseHeight = i;

    g.beginFill( fillcolor, fillalpha );

    g.lineStyle( thickness, lineColor, lineAlpha, pixelHinting, scaleMode, caps, joints, miterLimit );

    g.drawRoundRect( offset_x + half_thickness, offset_y + half_thickness, rectWidth - thickness, rectHeight - thickness, ellipseWidth, ellipseHeight );

}

//Draw rectangles of heights 105 through 110

//observe anomalous bevel at 106 and 110

ellipseWidth = ellipseHeight = 5;

offset_y = 150;

rectWidth = 120;

for (var j:int = 0; j < 6; j++)

{

    rectHeight = 105 + j;

    thickness = 60;

    if (thickness > (rectHeight / 2))

        thickness = (rectHeight / 2);

    if (thickness > (rectWidth / 2))

        thickness = (rectWidth / 2);

    miterLimit = thickness;

    offset_x = j * (rectWidth + 10); //offset each subsequent rectangle to the right

    g.beginFill( fillcolor, fillalpha );

    g.lineStyle( thickness, lineColor, lineAlpha, pixelHinting, scaleMode, caps, joints, miterLimit );

    g.drawRoundRect( offset_x + half_thickness, offset_y + half_thickness, rectWidth - thickness, rectHeight - thickness, ellipseWidth, ellipseHeight );

    g.endFill();

}

//Draw rectangle around 2nd set of shapes to make height increase more obvious

g.lineStyle( 0, 1 );

g.drawRect( -1, 148, 130 * 6 + 1, 110 );

TOPICS
ActionScript
391
Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Enthusiast ,
Jun 19, 2014 Jun 19, 2014
LATEST

If you set Caps to None and joints to Round you get much better results...

var caps:String = flash.display.CapsStyle.NONE;

var joints:String = flash.display.JointStyle.ROUND;

rects.jpg

Translate
Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines