I have a XYChart whose ticks unit is set to 25 for X axis.
The chart has a sliding functionality. Each time I slide left or right, I want the ticks to stay constant. So far, I have 10 or 11 ticks, set at 25 distance one to another, and they change their values -- I want that constant.
For example:
lowerBound = 480
upperBound = 600
Ticks: 480, 505, 530, 555, 580, 600.
I slide right: I still want to see 480, 505, 530, 555, 580, 600 at different positions though, and possible get rid of 480 and see 605, 630 if I went enough to the right...
Kindly Advise.
Fixed it:
wrote a new class similar to NumberAxis, except calculateTickValues is implemented using my own logic:
if (lowerBound + tickUnit < upperBound) {
double start = lowerBound;
while ((int)start % (int)tickUnit != 0) {
start++;
}
int count = (int)Math.ceil((upperBound - start)/tickUnit);
for (int i = 0; start < upperBound && i < count; start += tickUnit, i++) {
if (!tickValues.contains(start)) {
tickValues.add((int) start);
}
}
}
Here tickUnit=25, as set up on a Chart class I am using, which extends AbstractBaseChart.
It is not very elegant but it works.
Related
I am working QCustomPlot with Qt and need to change the color of a particular vertical grid line within the graph please let us know how we can change that I attached the image of my requirement.
The bleo code solve the issue
GraphTesting(QCustomPlot * customPlot)
{
// generate some data:
QVector<double> x(101), y(101); // initialize with entries 0..100
for (int i = 0; i < 101; ++i)
{
x[i] = i; //i / 50.0 - 1; // x goes from -1 to 1
y[i] = x[i]/2; // let's plot a quadratic function
}
// create graph and assign data to it:
customPlot->addGraph();
customPlot->graph(0)->setData(x, y);
// give the axes some labels:
customPlot->xAxis->setLabel("x");
customPlot->yAxis->setLabel("y");
customPlot->rescaleAxes();
QCPItemLine *step = new QCPItemLine(customPlot);
step->setPen(QPen(QColor(140, 0, 0)));
double begin = 25;
double first = customPlot->yAxis->range().lower;
double end = customPlot->yAxis->range().upper; //example values
step->start->setCoords(begin, first);
step->end->setCoords(begin, end);
customPlot->replot();
}
I have a dynamic programming exercise but I dont know how it will work in here:
We have a mysterious number is a string that consists of digits and asterisk *.
Given a mysterious number, count all the possible natural number to replace the asterisk * with a digit to produce an integer divisible by n.
For expample:
For 1*1* and n = 6 there are 16 possible numbers divisible by n: 1014,
1110,
1116,
1212,
1218,
1314,
1410,
1416,
1512,
1518,
1614,
1710,
1716,
1812,
1818,
1914.
If there is a leading asterisk then it should never be replaced by a zero:
*12 -> 112 (is okay) but *12 -> 012 (is not okay)
Input:
1 <= inputString.size <= 1000
1 <= n <= 1000
Time limit :
500ms in C++ language. As i said this is an dynamic programming exercise.
Can anyone give me some hints on this?
i write a JavaScript for you it work, you can change it to c++,
also leave comment for u. it use Recursive to handle and replace every * from left and replace it with possible numbers
var string = "sample mystriuos number"
function Func(mysNumber , n )
{
// this function
var realnumber = true // a check if number is not mystrius anymore!!
for (var i=0 ; i<= mysNumber.length ; i++)
{
if(i !=0 && mysNumber[i]=="*") // for Not left number
{
realnumber= false
for(var j=0 ; j<=9 ;j++ )
{
Func(mysNumber.substring(0,i) + j.toString() + mysNumber.substring(i+1,mysNumber.length) ,n)
}
}
else if (mysNumber[i]=="*") // for left number
{
realnumber = false
for(var j=1 ; j<=9 ;j++ )
{
Func(mysNumber.substring(0,i) + j.toString() + mysNumber.substring(i+1,mysNumber.length) ,n)
}
}
}
if(realnumber)
if(parseInt(mysNumber) % n ==0)
print(mysNumber)
}
func(string , 6)
I am building a game with libgdx.
The game screen is a grid with Scene2D actors. Actors are displayed on the front.
I would like to draw a background that looks like a checkerboard, coloring every 2 cells with one color and the other cells with another color.
It is easy to do but I was wondering if there are classes in libgdx that could optimize such a background, to make it as light and optimized as possible. For example, coloring each cell individually should work but doesn't seem like the best approach.
I have started to dig into the TiledMapTileLayer class but I'd have to fill each cell with a Tile object and that seems heavier than just a color.
Ideally, I would like to simply define 2 colors, set coordinates of the cells, and fill them with the colors without having to use objects or color the cells one by one.
What would be the best approach?
I think the most simple way would be, that you define 2 Tiles black and white or what ever and create an TiledMap on runtime just with those two tiles. It's just filling the cells in 2 for loops(x,y) with the same tiles. Should be easy to manage. Put the texture of it inside of one texture so you minimize the rendertime. You than dont need to handle the rendering and stuff like that yourself. You just need to implement the creation of the board with the TiledMap system. There is no solution where you can just define 2 colors. You always need to iterate over the cells somehow i think.
Take a look at the example code of libgdx for creating a tiledmap on runtime.
You can nearly copy paste it and just change this line
cell.setTile(new StaticTiledMapTile(splitTiles[ty][tx]));
Simply add the texture region for the back and white there depending on which cell you are currently are. something like this
if(y % 2 !=0){
cell.setTile(new StaticTiledMapTile(blackTextureRegion)); //or what color you need
}else{
cell.setTile(new StaticTiledMapTile(whiteTextureRegion)); //or what color you need
}
this would now create black and white rows. I recomend to use a Atlas for the TextureRegions or define them yourself.
Play around with the x and y values and check which you need. Maybe change the if statement i wrote to the right you need.
If you really just want to define a color you need to create a Pixmap with the 32x32 filled with the color on runtime and create a texture out of it. You can than use this to create the Tilemap as shown above.
Here is how you can create the 32x32 tiles you need. You can even create just one texture with 32x64 for both tiles. Just create the TextureRegions of 0,0,32,32 and 32,0,32,32.
Pixmap pixmap = new Pixmap(64, 32, Format.RGBA8888);
pixmap.setColor(Color.BLUE); // add your 1 color here
pixmap.fillRectangle(0, 0, 32, 32);
pixmap.setColor(Color.RED); // add your 2 color here
pixmap.fillRectangle(32, 0, 32, 32);
// the outcome is an texture with an blue left square and an red right square
Texture t = new Texture(pixmap);
TextureRegion reg1 = new TextureRegion(t, 0, 0, 32, 32);
TextureRegion reg2 = new TextureRegion(t, 32, 0, 32, 32);
//now use this to create the StaticTiledMapTile
If you glue this together you should have your system you would like to have.
Here you go:
Pixmap pixmap = new Pixmap(64, 32, Format.RGBA8888);
pixmap.setColor(Color.BLUE); // add your 1 color here
pixmap.fillRectangle(0, 0, 32, 32);
pixmap.setColor(Color.RED); // add your 2 color here
pixmap.fillRectangle(32, 0, 32, 32);
// the outcome is an texture with an blue left square and an red right
// square
Texture t = new Texture(pixmap);
TextureRegion reg1 = new TextureRegion(t, 0, 0, 32, 32);
TextureRegion reg2 = new TextureRegion(t, 32, 0, 32, 32);
TiledMap map = new TiledMap();
MapLayers layers = map.getLayers();
for (int l = 0; l < 20; l++) {
TiledMapTileLayer layer = new TiledMapTileLayer(150, 100, 32, 32);
for (int x = 0; x < 150; x++) {
for (int y = 0; y < 100; y++) {
Cell cell = new Cell();
if (y % 2 != 0) {
if (x % 2 != 0) {
cell.setTile(new StaticTiledMapTile(reg1));
} else {
cell.setTile(new StaticTiledMapTile(reg2));
}
} else {
if (x % 2 != 0) {
cell.setTile(new StaticTiledMapTile(reg2));
} else {
cell.setTile(new StaticTiledMapTile(reg1));
}
}
layer.setCell(x, y, cell);
}
}
layers.add(layer);
}
To render this you simply create an OrthogonalTiledMapRenderer and call the render() method.
In an minimum example this is the output:
already has some parameters for width and height and layercount. I think you wont need more than one layer
Code:
public class MainClass implements ApplicationListener {
private OrthographicCamera camera;
private OrthogonalTiledMapRenderer render;
private final static int width = 150, height = 100, layercount = 1;
private TiledMap map;
#Override
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera(w, h);
Pixmap pixmap = new Pixmap(64, 32, Format.RGBA8888);
pixmap.setColor(Color.BLUE); // add your 1 color here
pixmap.fillRectangle(0, 0, 32, 32);
pixmap.setColor(Color.RED); // add your 2 color here
pixmap.fillRectangle(32, 0, 32, 32);
// the outcome is an texture with an blue left square and an red right
// square
Texture t = new Texture(pixmap);
TextureRegion reg1 = new TextureRegion(t, 0, 0, 32, 32);
TextureRegion reg2 = new TextureRegion(t, 32, 0, 32, 32);
map = new TiledMap();
MapLayers layers = map.getLayers();
for (int l = 0; l < layercount; l++) {
TiledMapTileLayer layer = new TiledMapTileLayer(width, height, 32,
32);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
Cell cell = new Cell();
if (y % 2 != 0) {
if (x % 2 != 0) {
cell.setTile(new StaticTiledMapTile(reg1));
} else {
cell.setTile(new StaticTiledMapTile(reg2));
}
} else {
if (x % 2 != 0) {
cell.setTile(new StaticTiledMapTile(reg2));
} else {
cell.setTile(new StaticTiledMapTile(reg1));
}
}
layer.setCell(x, y, cell);
}
}
layers.add(layer);
}
render = new OrthogonalTiledMapRenderer(map);
render.setView(camera);
camera.translate(Gdx.graphics.getWidth() / 2,
Gdx.graphics.getHeight() / 2);
}
#Override
public void dispose() {
render.dispose();
map.dispose();
}
private static final float movmentspeed = 5f;
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
render.setView(camera);
render.render();
if (Gdx.input.isKeyPressed(Keys.LEFT)) {
camera.translate(-movmentspeed, 0);
} else if (Gdx.input.isKeyPressed(Keys.RIGHT)) {
camera.translate(movmentspeed, 0);
} else if (Gdx.input.isKeyPressed(Keys.UP)) {
camera.translate(0, movmentspeed);
} else if (Gdx.input.isKeyPressed(Keys.DOWN)) {
camera.translate(0, -movmentspeed);
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
In the end. i can't tell you if this is efficient! Maybe there are more efficient ways but this create your thing on runtime and if you dont do the creation over and over again it shouldn't be a problem since you just do it once you load the game for example. I think its efficient because the render is efficient and just draw the tiles that are visible on the screen. Moreover you just use 1 Texture for the background so its just one OpenGl bind for the whole background.
You could always just use ShapeRenderer to create a bunch of filled squares - http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/graphics/glutils/ShapeRenderer.html
How would you go about changing the steepness as for loops progress. Essentially I've made a terrain with vertices which form a valley. The creation of the data for these vertices to use is here:
// Divides it to a sensible height
const int DIVISOR_NUMBER = 40;
for (int x = 0; x < TerrainWidth; x++)
{
float height = Math.Abs(((float)x - ((float)TerrainWidth / 2))/ (float)DIVISOR_NUMBER);
for (int y = 0; y < TerrainHeight; y++)
{
float copyOfHeight = height;
float randomValue = random.Next(0, 3);
copyOfHeight += randomValue / 10;
HeightData[x, y] = copyOfHeight;
}
}
This works fine. But I now want to make the sides of the valley steeper at the start and end of the first loop and the valley flatten the closer to the center it gets. I'm having a bit of a mental block and can't think of a good way of doing it. Any help would be appreciated.
You can use a squared (aka quadratic) curve for that. Try:
float offset = (float)x - (float)TerrainWidth/2;
float height = offset*offset*SCALE_FACTOR;
If you still want a "crease" at the bottom of the valley, you can make your height a weighted sum:
float height = Math.Abs(offset) * ABS_FACTOR + offset*offset * QUADRATIC_FACTOR;
In this answer to my recent question, there is some code that draws a graph, but I can't manage to edit it into something that accepts any list of points as a parameter.
I'd like the Drawing method to accept these parameters:
List of Vector2, Point or VertexPositionColor, I can work with whichever.
Offset for the whole graph
These optional requirements would be appreciated:
Color that may override VertexPositionColor's color and apply to all points.
Size of the graph, so it can be shrunk or expanded, either as Vector2 as multiplier, or Point as target size. Maybe even combine this with offset in Rectangle.
And if it's possible, I'd like to have it all in a class, so graphs can be used separately from each other, each with its own Effect.world matrix, etc.
Here is that code (by Niko Drašković):
Matrix worldMatrix;
Matrix viewMatrix;
Matrix projectionMatrix;
BasicEffect basicEffect;
VertexPositionColor[] pointList;
short[] lineListIndices;
protected override void Initialize()
{
int n = 300;
//GeneratePoints generates a random graph, implementation irrelevant
pointList = new VertexPositionColor[n];
for (int i = 0; i < n; i++)
pointList[i] = new VertexPositionColor() { Position = new Vector3(i, (float)(Math.Sin((i / 15.0)) * height / 2.0 + height / 2.0 + minY), 0), Color = Color.Blue };
//links the points into a list
lineListIndices = new short[(n * 2) - 2];
for (int i = 0; i < n - 1; i++)
{
lineListIndices[i * 2] = (short)(i);
lineListIndices[(i * 2) + 1] = (short)(i + 1);
}
worldMatrix = Matrix.Identity;
viewMatrix = Matrix.CreateLookAt(new Vector3(0.0f, 0.0f, 1.0f), Vector3.Zero, Vector3.Up);
projectionMatrix = Matrix.CreateOrthographicOffCenter(0, (float)GraphicsDevice.Viewport.Width, (float)GraphicsDevice.Viewport.Height, 0, 1.0f, 1000.0f);
basicEffect = new BasicEffect(graphics.GraphicsDevice);
basicEffect.World = worldMatrix;
basicEffect.View = viewMatrix;
basicEffect.Projection = projectionMatrix;
basicEffect.VertexColorEnabled = true; //important for color
base.Initialize();
}
And the drawing method:
foreach (EffectPass pass in basicEffect.CurrentTechnique.Passes)
{
pass.Apply();
GraphicsDevice.DrawUserIndexedPrimitives<VertexPositionColor>(
PrimitiveType.LineList,
pointList,
0,
pointList.Length,
lineListIndices,
0,
pointList.Length - 1
);
}
The Graph class that does the requested can be found here.About 200 lines of code seemed too much to paste here.
The Graph is drawn by passing a list of floats (optionally with colors) to its Draw(..) method.
Graph properties are:
Vector2 Position - the bottom left corner of the graph
Point Size - the width (.X) and height (.Y) of the graph. Horizontally, values will be distributed to exactly fit the width. Vertically, all values will be scaled with Size.Y / MaxValue.
float MaxValue - the value which will be at the top of the graph. All off the chart values (greater than MaxValue) will be set to this value.
GraphType Type - with possible values GraphType.Line and GraphType.Fill, determines if the graph will be drawn line only, or bottom filled.
The graph is drawn with a line list / triangle strip.