Mantis Bugtracker
  

Viewing Issue Simple Details Jump to Notes ] View Advanced ] Issue History ] Print ]
ID Category Severity Reproducibility Date Submitted Last Update
0000877 [Squeak] Graphics minor always 02-13-05 03:58 08-08-07 14:19
Reporter wiz View Status public  
Assigned To andreas
Priority normal Resolution open  
Status assigned   Product Version
Summary 0000877: Radial Gradient Fill renders incorrectly when both scaled and rotated.
Description In the accompaning picture you see that radial gradient has a glitch.
When the gradient is both scaled and rotated there are two sections that are being misdrawn. In the acute angles between the y axis and the long axis of the ellipse the gradient is being rendered as a linear gradient. The linear gradient matches either the long axis or the y axis depending on which is left most.

In the picture the direction is always torward the center of the larger rectangle.
Additional Information This bug ties in with 0000851, 0000857
Attached Files  Radial Gradient Analyzed.jpeg [^] (60,905 bytes) 02-13-05 03:58
 FillTest-wiz.1.cs [^] (3,747 bytes) 02-13-05 05:52
 RadialXMidline.jpeg [^] (60,031 bytes) 03-08-05 22:58
 FillTest-wiz.1.cs.gz [^] (1,284 bytes) 03-08-05 22:59
 FillTest-wiz.2.cs.gz [^] (1,284 bytes) 03-08-05 23:01
 FillTest-wiz.2.cs [^] (7,071 bytes) 03-08-05 23:01

- Relationships

- Notes
(0001193 - 4540 - 8598 - 8598 - 8598 - 8598 - 8598)
wiz
02-28-05 03:33

closing in on the problem (and its solution).

Code diving into the VMMaker Balloon Plugin shows the problem clearly is to use of "self fillOriginXOf: fill" to determine the midpoint at which the fill goes from decreasing to increasing.
This occurs in two places in the code for radial fill.
Substituting the Xpoint allong the long axis of the ellipse for the appropriate yValue of the line should fix the problem. The best place to do that would be in the upper routine then is should just pass Xleft and Xmid to the decrease filler and xMid to Xright to the increase filler.

The test against "self fillOriginXOf: fill" in the decrease filler should be eliminated. (since it has been predicided.

O.K. I've found the bug. Now I need a VM keeper and advocate of bug free (ah bug reduced) squeak to step in and correct the vm stuff.

Can I get some help here???





!BalloonEnginePlugin methodsFor: 'fills-gradient' stamp: 'ar 11/24/1998 19:02'!
fillRadialGradient: fill from: leftX to: rightX at: yValue
    "Draw a radial gradient fill."
    | x x1 ramp rampSize dsX ds dtX dt length2 deltaX deltaY deltaST |
    self inline: false.
    self var: #ramp declareC:'int *ramp'.
    self var: #deltaST declareC:'int *deltaST'.

    ramp _ self gradientRampOf: fill.
    rampSize _ self gradientRampLengthOf: fill.

    deltaX _ leftX - (self fillOriginXOf: fill).
    deltaY _ yValue - (self fillOriginYOf: fill).

    dsX _ self fillDirectionXOf: fill.
    dtX _ self fillNormalXOf: fill.

    ds _ (deltaX * dsX) + (deltaY * (self fillDirectionYOf: fill)).
    dt _ (deltaX * dtX) + (deltaY * (self fillNormalYOf: fill)).


    x _ leftX.
    x1 _ rightX.

    "Note: The inner loop has been divided into three parts for speed"
    "Part one: Fill everything outside the left boundary"
    length2 _ (rampSize-1) * (rampSize-1). "This is the upper bound"
    [(self squaredLengthOf: ds // 16r10000 with: dt // 16r10000) >= length2 and:[x < x1]]
        whileTrue:[ x _ x + 1. ds _ ds + dsX. dt _ dt + dtX].
    x > leftX ifTrue:[self fillColorSpan: (self makeUnsignedFrom: (ramp at: rampSize-1)) from: leftX to: x].

    "Part two: Fill everything inside the boundaries"
    deltaST _ self point1Get.
    deltaST at: 0 put: ds.
    deltaST at: 1 put: dt.
    (x < (self fillOriginXOf: fill)) "<-- *** BUG*** "
             ifTrue:[
        "Draw the decreasing part"
        self aaLevelGet = 1
            ifTrue:[x _ self fillRadialDecreasing: fill ramp: ramp deltaST: deltaST
                            dsX: dsX dtX: dtX from: x to: x1]
            ifFalse:[x _ self fillRadialDecreasingAA: fill ramp: ramp deltaST: deltaST
                            dsX: dsX dtX: dtX from: x to: x1].
    ].
    x < x1 ifTrue:[
        "Draw the increasing part"
        self aaLevelGet = 1
            ifTrue:[x _ self fillRadialIncreasing: fill ramp: ramp deltaST: deltaST
                            dsX: dsX dtX: dtX from: x to: x1]
            ifFalse:[x _ self fillRadialIncreasingAA: fill ramp: ramp deltaST: deltaST
                            dsX: dsX dtX: dtX from: x to: x1].
    ].

    "Part three fill everything outside right boundary"
    x < rightX ifTrue:[self fillColorSpan: (self makeUnsignedFrom: (ramp at: rampSize-1)) from: x to: rightX].
! !

BalloonEnginePlugin methodsFor: 'fills-gradient' stamp: 'ar 11/24/1998 19:02'!
fillRadialDecreasing: fill ramp: ramp deltaST: deltaST dsX: dsX dtX: dtX from: leftX to: rightX
    "Part 2a) Compute the decreasing part of the ramp"
    | ds dt rampIndex rampValue length2 x x1 nextLength |
    self inline: true.
    ds _ (self cCoerce: deltaST to:'int*') at: 0.
    dt _ (self cCoerce: deltaST to:'int*') at: 1.
    rampIndex _ self accurateLengthOf: ds // 16r10000 with: dt // 16r10000.
    rampValue _ self makeUnsignedFrom: ((self cCoerce: ramp to:'int *') at: rampIndex).
    length2 _ (rampIndex-1) * (rampIndex-1).

    x _ leftX.
    x1 _ rightX.
    x1 > (self fillOriginXOf: fill) ifTrue:[x1 _ self fillOriginXOf: fill]. "<-- *** BUG*** "
    [x < x1] whileTrue:[
        "Try to copy the current value more than just once"
        [x < x1 and:[(self squaredLengthOf: ds // 16r10000 with: dt // 16r10000) >= length2]]
            whileTrue:[ spanBuffer at: x put: rampValue.
                        x _ x + 1.
                        ds _ ds + dsX.
                        dt _ dt + dtX].
        "Step to next ramp value"
        nextLength _ self squaredLengthOf: ds // 16r10000 with: dt // 16r10000.
        [nextLength < length2] whileTrue:[
            rampIndex _ rampIndex - 1.
            rampValue _ self makeUnsignedFrom: ((self cCoerce: ramp to:'int *') at: rampIndex).
            length2 _ (rampIndex-1) * (rampIndex-1).
        ].
    ].

    (self cCoerce: deltaST to: 'int *') at: 0 put: ds.
    (self cCoerce: deltaST to: 'int *') at: 1 put: dt.
    ^x! !
 
(0001237 - 754 - 802 - 802 - 802 - 802 - 802)
wiz
03-08-05 23:21

Further analysis of tilted ellipses (had to remember/recreate a lot of my high school analytic geometry) gives the correct slope for the x midpoint as a fuction of the gradientfill orientation. To wit:

slope := fill direction y * fill direction x + (fill normal y * fill normal x) / (fill direction y squared + fill normal y squared).

I updated fill test to add the midline slope to the radial fill test examples as can be seen in the RadialXMidline picture.

The new fill test has been loaded.

Some way of calculating, storing and using the correct midpoint slope in the plugin package will make radial gradients correct for all orientations that represent ellipses. i.e as long as normal and direction points are orthoganal to each other.
 
(0003284 - 151 - 163 - 163 - 163 - 163 - 163)
wiz
12-12-05 03:41

The catagory for this should be graphics so Andreas might give it a look.

It could use the help of someone who bests knows how to modify the plugin.
 
(0003292 - 71 - 71 - 71 - 71 - 71 - 71)
cdegroot
12-12-05 15:59

Andreas - could you take a peek at this one? It's clearly beyond me :-)
 

- Issue History
Date Modified Username Field Change
02-13-05 03:58 wiz New Issue
02-13-05 03:58 wiz File Added: Radial Gradient Analyzed.jpeg
02-13-05 05:52 wiz File Added: FillTest-wiz.1.cs
02-28-05 03:33 wiz Note Added: 0001193
03-08-05 22:58 wiz File Added: RadialXMidline.jpeg
03-08-05 22:59 wiz File Added: FillTest-wiz.1.cs.gz
03-08-05 23:01 wiz File Added: FillTest-wiz.2.cs.gz
03-08-05 23:01 wiz File Added: FillTest-wiz.2.cs
03-08-05 23:21 wiz Note Added: 0001237
12-12-05 03:41 wiz Note Added: 0003284
12-12-05 15:59 cdegroot Note Added: 0003292
12-12-05 15:59 cdegroot Status new => assigned
12-12-05 15:59 cdegroot Assigned To  => andreas
08-08-07 14:19 KarlRamberg Category Any => Graphics


Mantis 1.0.8[^]
Copyright © 2000 - 2007 Mantis Group
63 total queries executed.
40 unique queries executed.
Powered by Mantis Bugtracker