Stupid question about arcs (SOLVED)

gui

#1

Hi,
I want to change the layout of a rotary slider. So I create a subclass of LookAndFeel_4 and override the “drawRotarySlider” method.
First, when the slider is at its maximal position, I want to draw half of an ellipse clockwise from the 9 o’clock position to the 3 o’clock position via 12 o’clock that fills the region. The following code does the trick:
p.addArc(x,y,width,(2height),1.5float_Pi,2.5float_Pi,true);
I didn’t understand why I have to take (2
height), but OK. Now I try to draw part of an ellipse that starts at 9 o’clock but stops before 3 o’clock depending on the value of the slider. So I try the following code:
p.addArc(x,y,width,(2height),1.5float_Pi,(1,5float_Pi)+(sliderPosfloat_Pi),true);
But it doesn’t work. If I have sliderPos around 0,5, the curve isn’t seen. If I have sliderPos around 0,2 or 0,8, I see a half of an ellipse but smaller and translated rather than a very little (or large) part of half of an ellipse.
It confirms that I didn’t understand how addArc works and the documentation and the examples found don’t give any clue in which direction to search.
Can anyone explain to me the exact behavior of addArc and how I can reach my goal.
Thanks.


#2

The height is the height a full ellipse would be just inside. Even if you just draw a half ellipse, you need to supply the whole rectangle.

This angle can be greater than 2*Pi, so for example to draw a curve clockwise from the 9 o'clock position to the 3 o'clock position via 12 o'clock, you'd use 1.5*Pi and 2.5*Pi as the start and finish points.

I think, best would be if you post your full code (that paint method), and make sure you use 4 spaces or tripple back ticks, as the markup choked all your mathematical symbols.

Good luck


#3

The method is below. The idea is to create a slider like the one in Equator. It works when sliderPos=0 or sliderPos=1, but with intermediate values the (half of) the ellipses aren’t shown as I want.
Thanks.

//-----------------------------------------------------------------------------
void JDarwinLookAndFeel::drawRotarySlider(Graphics& g, int x, int y, int width, int height, float sliderPos,const float rotaryStartAngle, const float rotaryEndAngle, Slider& slider)
{
	// Some computations
	const float centreX=width/2.0f;
	const float lineLength=centreX*0.9f;
	const float begin=1.5f*float_Pi;
	const float middle=(1.5f+sliderPos)*float_Pi;
	const float end=2.5f*float_Pi;

	// Draw half of an ellipse that starts at 9 o'clock and stops at sliderPos (0.5->12 o'clock; 1->3 o'clock)
	Path p;
	p.addArc(x+5.0f,y+5.0f,width-10.0f,(height-5.0f)*2.0f,begin,middle,true);
	g.setColour (Colours::blue);
	g.fillPath(p);

	// Draw half of an ellipse that starts at sliderPos and stops at 3 o'clock
	if(middle!=end)
	{
		p.clear();
		p.addArc(x+5.0f,y+5.0f,width-10.0f,(height-5.0f)*2.0f,middle,end,true);
		g.setColour(Colours::darkgrey);
		g.fillPath(p);
	}

	// Draw half of an ellipse to repaint a background
	p.clear();
	p.addArc(x+12.0f,y+10.0f,width-24.0f,(height-10.0f)*2.0f,begin,end,true);
	g.setColour(Colours::black);
	g.fillPath(p);

	// Draw a line that represents sliderPos
	p.clear();
	p.addRectangle(-1.0f,-lineLength,1.0,lineLength);
	p.applyTransform (AffineTransform::rotation(middle-2.0f*float_Pi).translated(x+centreX,y+height));
	g.setColour(Colours::white);
	g.fillPath(p);
}

#4

Hello,
I found the reason: the arc must be closed with a segment in order to fill the whole space “under”. Here under the code that works (note the lineTo and addLineSegment instructions).

//-----------------------------------------------------------------------------
void JDarwinLookAndFeel::drawRotarySlider(Graphics& g, int x, int y, int width, int height, float sliderPos,const float rotaryStartAngle, const float rotaryEndAngle, Slider& slider)
{
	// Some computations
	const float centreX=width/2.0f;
	const float lineLength=centreX*0.9f;
	const float begin=1.5f*float_Pi;
	const float middle=(1.5f+sliderPos)*float_Pi;
	const float end=2.5f*float_Pi;

	// Draw half of an ellipse that starts at 9 o'clock and stops at sliderPos (0.5->12 o'clock; 1->3 o'clock)
	Path p;
	p.addArc(x+5.0f,y+5.0f,width-10.0f,(height-5.0f)*2.0f,begin,middle,true);
	Point<float> whereValue=p.getCurrentPosition();
	p.lineTo(centreX,y+height);
	g.setColour(JDarwinLookAndFeel::getSliderSelectedColour());
	g.fillPath(p);

	// Draw half of an ellipse that starts at sliderPos and stops at 3 o'clock
	if(middle!=end)
	{
		p.clear();
		p.addLineSegment(Line<float>(centreX,y+height,whereValue.x,whereValue.y),1.0f);
		p.addArc(x+5.0f,y+5.0f,width-10.0f,(height-5.0f)*2.0f,middle,end);
		g.setColour(JDarwinLookAndFeel::getSliderUnselectedColour());
		g.fillPath(p);
	}

	// Draw half of an ellipse to repaint a background
	p.clear();
	p.addArc(x+12.0f,y+10.0f,width-24.0f,(height-10.0f)*2.0f,begin,end,true);
	g.setColour(JDarwinLookAndFeel::getBackgroundColour());
	g.fillPath(p);

	// Draw a line that represents sliderPos
	p.clear();
	p.addRectangle(-1.0f,-lineLength,1.0,lineLength);
	p.applyTransform (AffineTransform::rotation(middle-2.0f*float_Pi).translated(x+centreX,y+height));
	g.setColour(Colours::white);
	g.fillPath(p);
}