Simple Math Equations in Android App - math

This is my first time posting, and after trying several different versions of solutions, I'm at the point where I think what I'm asking for is a bit beyond what I'm able to do at this point.
I am currently creating a simple app for my company that will be used as a sales tool. In my industry, it would be immensely helpful for the salesman in the field to be able to enter dimensions to get quick quotes for the customer.
What I am looking to try and do is to have a text field that will allow the salesperson to enter L (length), W (width), and D (depth).
Behind the scenes (java) the L would go through a simple math equation that takes into account predetermined allowances. The answer would then be put into a results area that would let them know the blank size of the project.
ex. L = 8.0625 ---> ((D*2)+.125)*2 + L ---> Blank Length = 14.625
I realize that may seem a little confusing, but it really is just supposed to be a simple equation that uses user entered information, adding to a static equation, and then posting the results on the same page.
EDIT: I solved aspects of it, but now I'm getting a crash as I try to go from whole numbers to decimals. I can do 6 as an input, but not 6.25. Any advice?
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_test4"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context="com.design.test4">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:text="Length"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:textSize="20dp"
android:id="#+id/length1"
android:gravity="right"
android:hint="Enter" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:paddingRight="30dp"
android:text="Width"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:textSize="20dp"
android:id="#+id/width1"
android:gravity="right"
android:hint="Enter" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:paddingRight="30dp"
android:text="Depth"/>
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number"
android:ems="10"
android:textSize="20dp"
android:id="#+id/depth1"
android:gravity="right"
android:hint="Enter" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content">
<Button
android:text="B Flute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="#+id/button"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:onClick="onButtonClick1" />
<Button
android:text="C Flute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerVertical="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:id="#+id/button2"
android:layout_marginTop="10dp"
android:layout_marginBottom="20dp"
android:onClick="onButtonClick2" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:paddingRight="30dp"
android:text="Blank Width"/>
<TextView
android:text="Answer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/depth1"
android:textSize="20dp"
android:gravity="right"
android:id="#+id/blank_width1" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20dp"
android:paddingRight="30dp"
android:text="Blank Length"/>
<TextView
android:text="Answer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="right"
android:textSize="20dp"
android:id="#+id/blank_length1" />
</LinearLayout>
</LinearLayout>
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test4);
}
double ba_width = (2.625);
double ba_length = (.625);
public void onButtonClick1(View v){
EditText e1 = (EditText)findViewById(R.id.length1);
EditText e2 = (EditText)findViewById(R.id.width1);
EditText e3 = (EditText)findViewById(R.id.depth1);
TextView t1 = (TextView)findViewById(R.id.blank_width1);
TextView t2 = (TextView)findViewById(R.id.blank_length1);
double num1 = Integer.parseInt(e1.getText().toString());
double num2 = Integer.parseInt(e2.getText().toString());
double num3 = Integer.parseInt(e3.getText().toString());
double sum1 = num1 + (num3 + num3 + ba_width);
double sum2 = num2 + (num3 + num2 + num3 + num2 + num3 + ba_length);
t1.setText(Double.toString(sum1));
t2.setText(Double.toString(sum2));
}
double ca_width = (3.25);
double ca_length = (.6875);
public void onButtonClick2(View v) {
EditText e1 = (EditText) findViewById(R.id.length1);
EditText e2 = (EditText) findViewById(R.id.width1);
EditText e3 = (EditText) findViewById(R.id.depth1);
TextView t1 = (TextView) findViewById(R.id.blank_width1);
TextView t2 = (TextView) findViewById(R.id.blank_length1);
double num1 = Integer.parseInt(e1.getText().toString());
double num2 = Integer.parseInt(e2.getText().toString());
double num3 = Integer.parseInt(e3.getText().toString());
double sum1 = num1 + (num3 + num3 + ca_width);
double sum2 = num2 + (num3 + num2 + num3 + num2 + num3 + ca_length);
t1.setText(Double.toString(sum1));
t2.setText(Double.toString(sum2));
}
}

Related

How to emit() only complete path or terminated by repeat loop?

My Graph looks like above image. It is simplified form of optical communication network. each vertex transmits one color. when two colors joins ("Mux") then it creates new color and transmits new light. At remote end colours are demuxed and passed to corresponding vertices.
Mux,demux and transmit("straight") are captured as edge. New colors are formed as per vent diagram.
If I start from one color (ex. "Red"), then I have to traverse only through edge which have red (R1,R2) or red shade (D1,D2,P1).
For Example, If I start from R1, then I can traverse [R1,D1,D2,P1,R2]. it has another path [R1,D1,D2,P1,K1,R2] But it is not valid. As K1 doesn't have red shade.
Below query works well. I store the color while traversing through "mux" edge. And use this color to pick demux edge.
g.V().hasLabel("R1").
repeat(choose(values("type")).
option("mux", aggregate(local, "colors").by("color").inV()).
option("demux", filter(values("color").as("c").
where("c", new P(new BitiseAndPredicate(), "colors")).
by().
by(unfold().limit(1))
).inV()).
option("stright", __.inV()).simplePath()).
until(hasLabel("R2")).
path().by(label()).toList();
For Input "R1" to "R2" it works fine. [R1,tx,D1,tx,D2,tx,P1,tx,R2]
For "Y1" to "Y2" it returns empty. It is correct , As there is no edge from G1 to Y1.
I want to make changes to query. If it is not able to reach destination then print till where it reached .In this case [Y1,tx,D1,tx,D2,tx,G1]
I used emit(). But it prints all path combination along the path.
g.V().hasLabel("R1").
repeat(choose(values("type")).
option("mux", aggregate(local, "colors").by("color").inV()).
option("demux", filter(values("color").as("c").
where("c", new P(new BitiseAndPredicate(), "colors")).
by().
by(unfold().limit(1))
).inV()).
option("stright", __.inV()).simplePath()).
until(hasLabel("R2")).emit().
path().by(label()).toList();
If it is simple traversal then I can use emit(out().count().is(eq('0'))). But in this case last edge have more edges, but not it is matching with my "mux & demux" condition. I can't reuse the same condition in "repeat" step. Actual implementation will be more complex.
Is there any way to emit path if until condition met or repeat step doesn't return any vertex.
Here is Java code
import org.apache.tinkerpop.gremlin.process.traversal.P;
import org.apache.tinkerpop.gremlin.process.traversal.Path;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversalSource;
import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.apache.tinkerpop.gremlin.util.function.Lambda;
import org.janusgraph.core.*;
import org.janusgraph.core.schema.JanusGraphManagement;
import java.util.ArrayList;
import java.util.List;
import static org.apache.tinkerpop.gremlin.process.traversal.P.eq;
import static org.apache.tinkerpop.gremlin.process.traversal.P.without;
import static org.apache.tinkerpop.gremlin.process.traversal.Scope.local;
import static org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__.*;
import static org.janusgraph.core.Multiplicity.MULTI;
public class ColourTraversal
{
public static void main( String[] args )
{
//External db
GraphTraversalSource g =null;
//inmemory db
JanusGraph graph = JanusGraphFactory.build().set("storage.backend", "inmemory").open();
g = graph.traversal();
try
{
populateData(g);
g.tx().commit();
printPath(g, "R1", "R2");
System.out.println();
printPath(g, "Y1", "Y2");
g.close();
} catch (Exception e)
{
e.printStackTrace();
}
}
private static void printPath(GraphTraversalSource g, String start, String end)
{
List<Path> pathList = g.V().hasLabel(start).
repeat(repeatStep().simplePath()).
emit(hasLabel(end)).
path().by(label()).toList();
for (Path path : pathList)
{
for (int i = 0; i < path.size(); i++)
{
String label = path.get(i);
System.out.println(label);
}
}
}
private static GraphTraversal<?, Vertex> repeatStep()
{
GraphTraversal<?, ?> repeatStepTrav =
outE("tx").choose(values("type")).
option("mux", aggregate(local, "colors").by("color").inV()).
option("demux", filter(values("color").as("c").
where("c", new P(new BitiseAndPredicate(), "colors")).
by().
by(unfold().limit(1))
).inV()).
option("stright", __.inV());
return (GraphTraversal<Vertex, Vertex>) repeatStepTrav;
}
private static void populateData(GraphTraversalSource g)
{
Vertex r1 = g.addV("R1").next();
Vertex r2 = g.addV("R2").next();
Vertex d1 = g.addV("D1").next();
Vertex d2 = g.addV("D2").next();
Vertex g1 = g.addV("G1").next();
Vertex b1 = g.addV("B1").next();
Vertex b2 = g.addV("B2").next();
Vertex b3 = g.addV("B3").next();
Vertex y1 = g.addV("Y1").next();
Vertex p1 = g.addV("P1").next();
addEdge(g, r1, d1, "mux", 4);
addEdge(g, y1, d1, "mux", 2);
addEdge(g, b1, d1, "mux", 1);
addEdge(g, d1, d2, "stright", 7);
addEdge(g, g1, d2, "mux", 3);
addEdge(g, p1, d2, "mux", 5);
addEdge(g, b2, g1, "mux", 1);
addEdge(g, b3,p1, "mux", 1);
addEdge(g, r2,p1, "mux", 4);
addEdge(g, d1, r1, "demux", 4);
addEdge(g, d1, y1, "demux", 2);
addEdge(g, d1, b1, "demux", 1);
addEdge(g, d2, d1, "stright", 7);
addEdge(g, d2,g1, "demux", 3);
addEdge(g, d2,p1, "demux", 5);
addEdge(g, g1,b2, "demux", 1);
addEdge(g, p1,b3, "demux", 1);
addEdge(g, p1,r2, "demux", 4);
Vertex k1 = g.addV("K1").next();
addEdge(g, p1, k1, "demux", 0);
addEdge(g, k1, r2, "demux", 0);
addEdge(g, k1, p1, "mux", 0);
addEdge(g, r2, k1, "mux", 0);
// Vertex y2 = g.addV("Y2").next();
// addEdge(g, y2, g1, "mux", 2);
// addEdge(g, g1,y2, "demux", 2);
}
private static void addEdge(GraphTraversalSource g, Vertex source, Vertex destination,String type,int color) {
GraphTraversal t = g.V(source).addE("tx").to(destination).property("type", type).property("color", color);
t.next();
}
}
import java.util.function.BiPredicate;
public class BitisetAndPredicate implements BiPredicate {
#Override
public boolean test(Object o, Object o2) {
int left = (int) o;
int right = (int) o2;
return (left & right) == right;
}
}
Instead of using the emit() step you can add a disjunct condition to the until() step, testing for paths that have no further out edges.
The session below in the gremlin console using the tinkerpop-modern sample graph shows how:
graph = TinkerFactory.createModern()
g = graph.traversal()
// Your old query
gremlin> g.V(1).repeat(out()).until(has("name", "ripple")).path()
==>[v[1],v[4],v[5]]
// A query with additional condition to stop the repeat
gremlin> g.V(1).repeat(out()).until(or(has("name", "ripple"), out().count().is(eq(0)))).path()
==>[v[1],v[3]]
==>[v[1],v[2]]
==>[v[1],v[4],v[5]]
==>[v[1],v[4],v[3]]

Using a vector as an array index?

Under OpenCL, is there a method for accessing an array using a vector as an index?
For example, I want to accomplish something like this:
__constant uint data[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
uchar4 keys = (uchar4)(5, 0, 2, 6);
uint4 results = data[keys];
// results = (uint4)(0x55, 0x00, 0x22, 0x66);
More generically:
// Array of scalar type T
T data[] = {value_0, value_1, ...};
// n-item vector of type V
Vn keys = (Vn)(index_0, index_1, ...);
// n-item vector of type T
Tn result = data[keys];
Currently, the only way I can accomplish something like this is to do it manually, but it doesn't feel very "vector-y":
__constant uint data[] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
uchar4 keys = (uchar4)(5, 0, 2, 6);
uint4 results = (uint4)(data[keys.s0], data[keys.s1], data[keys.s2], data[keys.s3]);
// results = (uint4)(0x55, 0x00, 0x22, 0x66);
So I guess this is a two part question:
Is there a way to access an array using a vector as an index?
If not, is there a more efficient way than I've showcased above?
OpenCL C is based on C99 standard, which doesn't allow array index to be vector.
Last sample of your code is pretty much what you can get. Also, take into account that using vector elements as array index leads to poor memory access pattern, which can decrease IO performance dramatically.

Jung Graph visualization: vertices displaying like christmas light

Please, help needed. I am trying to visualize a graph with jung but the vertices keeps moving about and changing color randomly. What I want to achieve is to display some vertices with a particular color (like having vertices with clusters distinguished by color) and then go on to visualize a path between two vertices of interest. The number of vertices are over 500. I am new to jung and to achieve this task, I have tried to modify a code I got from a thread on this forum. The code I am working with is shown below
import edu.uci.ics.jung.algorithms.layout.ISOMLayout;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.SparseGraph;
import edu.uci.ics.jung.visualization.RenderContext;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.control.ModalGraphMouse;
import edu.uci.ics.jung.visualization.renderers.Renderer;
import edu.uci.ics.jung.visualization.transform.shape.GraphicsDecorator;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Shape;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Point2D;
import java.util.Random;
import javax.swing.JFrame;
import org.apache.commons.collections15.Transformer;
public class graphMainHelp {
public static void main(String[] args) {
SparseGraph graph = new SparseGraph();
String[] vertices = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J"};
for (int i = 0; i < vertices.length; i++) {
graph.addVertex((String) vertices[i]);
}
graph.addEdge(1, "J", "A");
graph.addEdge(2, "A", "C");
graph.addEdge(3, "B", "A");
graph.addEdge(4, "B", "J");
graph.addEdge(5, "I", "E");
graph.addEdge(6, "B", "F");
graph.addEdge(7, "C", "A");
graph.addEdge(8, "G", "E");
graph.addEdge(9, "G", "F");
graph.addEdge(10, "H", "B");
graph.addEdge(11, "G", "C");
graph.addEdge(12, "E", "G");
graph.addEdge(13, "I", "B");
graph.addEdge(14, "F", "J");
graph.addEdge(15, "F", "E");
if (graph.getVertexCount() != 0 || graph.getEdgeCount() != 0) {
Layout<String, String> layout = new ISOMLayout<String, String>(graph);
layout.setSize(new Dimension(700, 700));
VisualizationViewer<String, String> vv = new VisualizationViewer<String, String>(layout);
vv.getRenderContext().setVertexLabelTransformer(new Transformer<String, String>() {
#Override
public String transform(String arg0) {
return arg0;
}
});
vv.getRenderer().setVertexRenderer(new MyRenderer());
final DefaultModalGraphMouse<String, Number> graphMouse = new
DefaultModalGraphMouse<String, Number>();
graphMouse.setMode(ModalGraphMouse.Mode.PICKING);
vv.setGraphMouse(graphMouse);
JFrame frame = new JFrame();
frame.getContentPane().add(vv);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}// close main method
}
static class MyRenderer implements Renderer.Vertex<String, String> {
#Override
public void paintVertex(RenderContext<String, String> rc, Layout<String, String> layout, String vertex) {
GraphicsDecorator graphicsContext = rc.getGraphicsContext();
Point2D center = layout.transform(vertex);
Shape shape = null;
Color color = null;
shape = new Ellipse2D.Double(center.getX() - 10, center.getY() - 10, 20, 20);
Random random = new Random();
int r = random.nextInt(256);
int g = random.nextInt(200);
int b = random.nextInt(250);
color = new Color(r, g, b);
graphicsContext.setPaint(color);
graphicsContext.fill(shape);
}
}//close static class
}
The vertices are changing color because you told them to: every time you render a vertex you are giving it a new random color to paint it. I don't understand why you're using a custom renderer at all, really. If you want to specify shape or color other than the default, look at PluggableRendererContext and the associated demo.
There are a number of demos in the JUNG download itself; I recommend that you take a look at them rather than starting with samples on StackOverflow.

How to find the Angle from pitch, roll and yaw?

I have an accelerometer and gyroscope embedded in a chip, from which I get the x,y,z axis (from accelerometer), pitch, roll and yaw (from gyroscope). Using these values, I have to rotate the 3D image. glRotatef(Angle,Xvector,Yvector,Zvector) How to find the Angle from pitch, roll and yaw? Any equation for this?
Those rotational values you receive from the gyroscope should not be treated as individual rotations about different axes, but time differential the compund rotation. You problem is of the form that you want to find the differential rotation matrix dR for which the differential components can be multiplied in arbitrary order to yield that matrix
dR = dR_x * dR_y * dR_z
= dR_y * dR_x * dR_z
= dR_y * dR_z * dR_x
= dR_z * dR_x * dR_y
= dR_z * dR_y * dR_x
The most easy way to do this, is calculate each of those permutations and take the average matrix of them being dR' and apply orthonormalization.
Then just use this matrix. Forget about glRotate, you don't need it and it got removed from later OpenGL versions anyway.
your answer for pitch & Yaw angle by android acceleration_sensor is:
double angle = Math.atan2(zVal, yVal)/(Math.PI/180) //for pitch
double angle = Math.atan2(xVal, yVal)/(Math.PI/180) //for Yaw
they are tested.
private SensorManager sensorManager;
TextView x;
TextView y;
TextView z;
TextView ang;
String sx, sy, sz;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.l1);
x = (TextView) findViewById (R.id.textView2);
y = (TextView) findViewById (R.id.textView3);
z = (TextView) findViewById (R.id.textView4);
ang = (TextView) findViewById(R.id.textView5);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor
(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
float xVal = event.values[0];
float yVal = event.values[1];
float zVal = event.values[2];
sx = "X Value : <font color = '#800080'> " + xVal + "</font>";
sy = "Y Value : <font color = '#800080'> " + yVal + "</font>";
sz = "Z Value : <font color = '#800080'> " + zVal + "</font>";
x.setText(Html.fromHtml(sx));
y.setText(Html.fromHtml(sy));
z.setText(Html.fromHtml(sz));
double angle = Math.atan2(zVal, xVal)/(Math.PI/180);
ang.setText(String.valueOf(angle));
}
}

Why Pixel Bender filter behaves differently in Toolkit than in Flex/Air application?

Ok, so I've tried this simpler filter with same Air code as below:
<languageVersion : 1.0;>
kernel NewFilter
< namespace : "Your Namespace";
vendor : "Your Vendor";
version : 1;
description : "your description";
>
{
input image4 src;
output pixel4 dst;
void
evaluatePixel()
{
pixel4 cPix = sampleNearest(src,outCoord());
pixel3 RGB = cPix .rgb;
float r = RGB.r;
float g = RGB.g;
float b = RGB.b;
//float minVal = min(r, g);
dst = pixel4(r, g, b, 1);
}
}
It turns out, that if I uncomment this line float minVal = min(r, g);, I do not get original picture any more, but this:
Result
Instead of this:
Original
If someone could explain this to me... I'd be very grateful...
//------------------------------------------------------------------
//------------------- ORIGINAL POST --------------------------------
I'm trying to make pixel bender filter for flex application, which changes selected range of hue values of input image to defined new hue value.
I made such filter in Pixel bender Toolkit, and it gives satisfactory results.
This is the code for that filter:
<languageVersion : 1.0;>
kernel ColorChange
< namespace : "Your Namespace";
vendor : "Your Vendor";
version : 1;
description : "your description";
>
{
input image4 src;
output pixel4 dst;
parameter float HUE
<
minValue: 0.;
maxValue: 359.9;
defaultValue: 0.;
>;
parameter float SAT
<
minValue: -1.;
maxValue: 1.;
defaultValue: 0.;
>;
parameter float VAL
<
minValue: -1.;
maxValue: 1.;
defaultValue: 0.;
>;
parameter float MIN_RANGE
<
minValue: 0.;
maxValue: 360.;
defaultValue: 0.;
>;
parameter float MAX_RANGE
<
minValue: 0.;
maxValue: 360.;
defaultValue: 360.;
>;
void
evaluatePixel()
{
pixel4 cPix = sample(src,outCoord());
pixel3 RGB = cPix.rgb;
float3 HSV;
//--------------------------------------------------------------
// CONVERT RGB TO HSV
//--------------------------------------------------------------
pixel1 r = RGB.r;
pixel1 g = RGB.g;
pixel1 b = RGB.b;
pixel1 minVal = min(min(r, g), b);
pixel1 maxVal = max(max(r, g), b);
pixel1 delta = maxVal - minVal;
HSV[2] = maxVal;
if (maxVal == 0.) {
HSV[0] = 0.;
HSV[1] = 0.;
}
else
{
HSV[1] = delta / maxVal;
}
if(r == maxVal)
HSV[0] = (g-b)/delta;
else if(g == maxVal)
HSV[0] = 2. + (b-r) / delta;
else
HSV[0] = 4. + (r-g) / delta;
HSV[0] *= 60.;
if(HSV[0] <0.)
HSV[0] += 360.;
//--------------------------------------------------------------
// FILTER RANGE OF HUE
//--------------------------------------------------------------
if((HSV[0] < MIN_RANGE) || (HSV[0] > MAX_RANGE))
{
dst = cPix;
}
else
{
//--------------------------------------------------------------
// CHNAGE HSV
//--------------------------------------------------------------
float hH = HUE;
float sS = SAT;
float vV = VAL;
HSV[0] = HUE;
HSV[1] += SAT;
if(HSV[1] > 1.)
HSV[1] = 1.;
else if(HSV[1] < 0.)
HSV[1] = 0.;
HSV[2] += VAL;
if(HSV[2] > 1.)
HSV[2] = 1.;
else if(HSV[2] < 0.)
HSV[2] = 0.;
//----------------------------------------------------------------------
// CONVERT HSV TO RGB
//----------------------------------------------------------------------
float h = HSV[0];// / 360.;
float s = HSV[1];// / 100. * 255.;
float v = HSV[2];// / 100. * 255.;
if (s == 0.) {
RGB.r = v;
RGB.g = v;
RGB.b = v;
} else {
h = h / 60.;
int var_i = int(floor(h));
float f = h - float(var_i);
float p = v * (1.-s);
float q = v * (1.-s*f);
float t = v * (1.-s*(1.-f));
if (var_i == 0) {
RGB.r = v;
RGB.g = t;
RGB.b = p;
}
else if (var_i == 1) {
RGB.r = q;
RGB.g = v;
RGB.b = p;
}
else if (var_i == 2) {
RGB.r = p;
RGB.g = v;
RGB.b = t;
}
else if (var_i == 3) {
RGB.r = p;
RGB.g = q;
RGB.b = v;
}
else if (var_i == 4) {
RGB.r = t;
RGB.g = p;
RGB.b = v;
}
else {
RGB.r = v;
RGB.g = p;
RGB.b = q;
}
}
dst = pixel4(RGB.r, RGB.g, RGB.b, 1);
}
}
}
So the principle is simple, convert every pixel to HSV color space, check if hue falls between selected range, if it does change it's hue to defined one and convert back to RGB.
The problem is, when used in Air application, I don't get the same results, starting from point of using only default parameters of filter.
This is the code of Air application:
<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
width="1400" height="800" backgroundAlpha="0.0" xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="windowedapplication1_creationCompleteHandler(event)">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import mx.events.ColorPickerEvent;
import mx.events.FlexEvent;
import spark.filters.ShaderFilter;
import spark.utils.BitmapUtil;
[Embed(source="myFilter.pbj", mimeType="application/octet-stream")]
private var MyBender:Class;
private var shader:Shader = new Shader();
private var shaderJob:ShaderJob;
private var shaderResult:BitmapData;
private function filter():void
{
// Configure desired input parameters of shader.
shader.data.src.input = originalImage.bitmapData;
// shader.data.HUE.value = [H_slider.value];
// shader.data.SAT.value = [S_slider.value];
// shader.data.VAL.value = [V_slider.value];
// shader.data.MAX_RANGE.value = [H_max_slider.value];
// shader.data.MIN_RANGE.value = [H_min_slider.value];
shaderJob = new ShaderJob(shader, shaderResult);
shaderJob.start(true);
bendedImage.source = new Bitmap(shaderResult);
}
private function windowedapplication1_creationCompleteHandler(event:FlexEvent):void
{
// Create new shader instance and initialize with embedded byte code.
shader = new Shader(new MyBender());
shaderResult = new BitmapData(originalImage.width, originalImage.height);
filter();
}
]]>
</fx:Script>
<s:HGroup width="100%">
<s:Group id="originalGroup" width="100%">
<s:Image id="originalImage" source="mandelbrot.png"/>
</s:Group>
<s:Group id="bendedGroup" width="100%">
<s:SWFLoader id="bendedImage" source="mandelbrot.png" />
<s:HSlider id="H_slider" minimum="0" maximum="359.9" stepSize="0.1" value="0" change="filter()" width="500" toolTip="HUE"/>
<s:HSlider id="S_slider" minimum="-1" maximum="1" stepSize="0.1" value="0" y="20" change="filter()" width="500" toolTip="SAT"/>
<s:HSlider id="V_slider" minimum="-1" maximum="1" stepSize="0.1" value="0" y="40" change="filter()" width="500" toolTip="VAL"/>
<s:HSlider id="H_max_slider" minimum="0" maximum="360" stepSize="0.1" value="360" y="60" change="filter()" width="500" toolTip="HUE MAX"/>
<s:HSlider id="H_min_slider" minimum="0" maximum="360" stepSize="0.1" value="0" y="80" change="filter()" width="500" toolTip="HUE MIN"/>
</s:Group>
</s:HGroup>
</s:WindowedApplication>
So, applying PixelBender filter in Air app with default parameters produces this:
http://i.stack.imgur.com/UyoZR.png
But in Pixel Bender Toolkit i see this with same parameters:
http://i.imgur.com/LNnCi.png
Changing HUE_MAX slider in app (binded to MAX_RANGE parameter of filter), it doesn't filter out HUE values smoothly, but instead thresholds at HUE_MAX=59.9, where at lower values looks like no filter is applyed, and at HUE_MAX=299.9 where between 60 and 299.9 looks like this:
http://i.stack.imgur.com/5kePu.png (sorry, new user)
Any ideas what am I doing wrong?
min function does somenthing to its parameters which i cannot explain.
But the problem is solved when using
pixel1 minVal = r;
if(g < minVal)
minVal = g;
if(b < minVal)
minVal = b;
instead of
pixel1 minVal = min(min(r, g), b);
You have a lot of float comparisons in your PB code. Lines like this:
if (maxVal == 0.)
are extrenely susceptable to rounding errors. I suggest using something like this instead:
if (abs(maxVal) < epsilon)
Your AS code has the lines that set the parameter values commented out. Can you try commenting them back in and set the values to the defaults. The default values you put into a PB file aren't automatically set by the runtime, they're just meant as hints to the UI.

Resources